odbccp32: Fix SQLInstallDriverManager{,W}.
[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 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47     ShowWindow(ret, SW_SHOW);
48     return ret;
49 }
50
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 {
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     c1 >>= 8; c2 >>= 8;
55     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56     c1 >>= 8; c2 >>= 8;
57     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58     c1 >>= 8; c2 >>= 8;
59     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60     return TRUE;
61 }
62
63 /* Locks a given surface and returns the color at (x,y).  It's the caller's
64  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 {
67     DWORD color;
68     HRESULT hr;
69     D3DSURFACE_DESC desc;
70     RECT rectToLock = {x, y, x+1, y+1};
71     D3DLOCKED_RECT lockedRect;
72
73     hr = IDirect3DSurface9_GetDesc(surface, &desc);
74     if(FAILED(hr))  /* This is not a test */
75     {
76         trace("Can't get the surface description, hr=%08x\n", hr);
77         return 0xdeadbeef;
78     }
79
80     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81     if(FAILED(hr))  /* This is not a test */
82     {
83         trace("Can't lock the surface, hr=%08x\n", hr);
84         return 0xdeadbeef;
85     }
86     switch(desc.Format) {
87         case D3DFMT_A8R8G8B8:
88         {
89             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90             break;
91         }
92         default:
93             trace("Error: unknown surface format: %d\n", desc.Format);
94             color = 0xdeadbeef;
95             break;
96     }
97     hr = IDirect3DSurface9_UnlockRect(surface);
98     if(FAILED(hr))
99     {
100         trace("Can't unlock the surface, hr=%08x\n", hr);
101     }
102     return color;
103 }
104
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 {
107     DWORD ret;
108     IDirect3DSurface9 *surf = NULL, *target = NULL;
109     HRESULT hr;
110     D3DLOCKED_RECT lockedRect;
111     RECT rectToLock = {x, y, x+1, y+1};
112
113     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114     if(FAILED(hr) || !surf )  /* This is not a test */
115     {
116         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117         return 0xdeadbeef;
118     }
119
120     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121     if(FAILED(hr))
122     {
123         trace("Can't get the render target, hr=%08x\n", hr);
124         ret = 0xdeadbeed;
125         goto out;
126     }
127
128     hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129     if(FAILED(hr))
130     {
131         trace("Can't read the render target data, hr=%08x\n", hr);
132         ret = 0xdeadbeec;
133         goto out;
134     }
135
136     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137     if(FAILED(hr))
138     {
139         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140         ret = 0xdeadbeeb;
141         goto out;
142     }
143
144     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145      * really important for these tests
146      */
147     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148     hr = IDirect3DSurface9_UnlockRect(surf);
149     if(FAILED(hr))
150     {
151         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
152     }
153
154 out:
155     if(target) IDirect3DSurface9_Release(target);
156     if(surf) IDirect3DSurface9_Release(surf);
157     return ret;
158 }
159
160 static IDirect3DDevice9 *init_d3d9(void)
161 {
162     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163     IDirect3D9 *d3d9_ptr = 0;
164     IDirect3DDevice9 *device_ptr = 0;
165     D3DPRESENT_PARAMETERS present_parameters;
166     HRESULT hr;
167     D3DADAPTER_IDENTIFIER9 identifier;
168
169     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171     if (!d3d9_create) return NULL;
172
173     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174     if (!d3d9_ptr)
175     {
176         skip("could not create D3D9\n");
177         return NULL;
178     }
179
180     ZeroMemory(&present_parameters, sizeof(present_parameters));
181     present_parameters.Windowed = TRUE;
182     present_parameters.hDeviceWindow = create_window();
183     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184     present_parameters.BackBufferWidth = 640;
185     present_parameters.BackBufferHeight = 480;
186     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187     present_parameters.EnableAutoDepthStencil = TRUE;
188     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
189
190     memset(&identifier, 0, sizeof(identifier));
191     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193     trace("Driver string: \"%s\"\n", identifier.Driver);
194     trace("Description string: \"%s\"\n", identifier.Description);
195     ok(identifier.Description[0] != '\0', "Empty driver description\n");
196     trace("Device name string: \"%s\"\n", identifier.DeviceName);
197     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
198     trace("Driver version %d.%d.%d.%d\n",
199           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
201
202     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203     if(FAILED(hr)) {
204         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206         if(FAILED(hr)) {
207             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
208         }
209     }
210     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
211
212     return device_ptr;
213 }
214
215 struct vertex
216 {
217     float x, y, z;
218     DWORD diffuse;
219 };
220
221 struct tvertex
222 {
223     float x, y, z, rhw;
224     DWORD diffuse;
225 };
226
227 struct nvertex
228 {
229     float x, y, z;
230     float nx, ny, nz;
231     DWORD diffuse;
232 };
233
234 static void lighting_test(IDirect3DDevice9 *device)
235 {
236     HRESULT hr;
237     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239     DWORD color;
240     D3DMATERIAL9 material, old_material;
241     DWORD cop, carg;
242
243     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244                       0.0f, 1.0f, 0.0f, 0.0f,
245                       0.0f, 0.0f, 1.0f, 0.0f,
246                       0.0f, 0.0f, 0.0f, 1.0f };
247
248     struct vertex unlitquad[] =
249     {
250         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
251         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
252         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
254     };
255     struct vertex litquad[] =
256     {
257         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
258         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
259         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
261     };
262     struct nvertex unlitnquad[] =
263     {
264         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268     };
269     struct nvertex litnquad[] =
270     {
271         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275     };
276     WORD Indices[] = {0, 1, 2, 2, 3, 0};
277
278     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
280
281     /* Setup some states that may cause issues */
282     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306
307     hr = IDirect3DDevice9_SetFVF(device, 0);
308     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309
310     hr = IDirect3DDevice9_SetFVF(device, fvf);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312
313     hr = IDirect3DDevice9_BeginScene(device);
314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315     if(hr == D3D_OK)
316     {
317         /* No lights are defined... That means, lit vertices should be entirely black */
318         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323
324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329
330         hr = IDirect3DDevice9_SetFVF(device, nfvf);
331         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332
333         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338
339         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344
345         IDirect3DDevice9_EndScene(device);
346         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
347     }
348
349     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
357
358     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359
360     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362     memset(&material, 0, sizeof(material));
363     material.Diffuse.r = 0.0;
364     material.Diffuse.g = 0.0;
365     material.Diffuse.b = 0.0;
366     material.Diffuse.a = 1.0;
367     material.Ambient.r = 0.0;
368     material.Ambient.g = 0.0;
369     material.Ambient.b = 0.0;
370     material.Ambient.a = 0.0;
371     material.Specular.r = 0.0;
372     material.Specular.g = 0.0;
373     material.Specular.b = 0.0;
374     material.Specular.a = 0.0;
375     material.Emissive.r = 0.0;
376     material.Emissive.g = 0.0;
377     material.Emissive.b = 0.0;
378     material.Emissive.a = 0.0;
379     material.Power = 0.0;
380     IDirect3DDevice9_SetMaterial(device, &material);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382
383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387
388     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396
397     hr = IDirect3DDevice9_BeginScene(device);
398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399     if(SUCCEEDED(hr)) {
400         struct vertex lighting_test[] = {
401             {-1.0,   -1.0,   0.1,    0x8000ff00},
402             { 1.0,   -1.0,   0.1,    0x80000000},
403             {-1.0,    1.0,   0.1,    0x8000ff00},
404             { 1.0,    1.0,   0.1,    0x80000000}
405         };
406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410
411         hr = IDirect3DDevice9_EndScene(device);
412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
413     }
414
415     color = getPixelColor(device, 320, 240);
416     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418
419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
431 }
432
433 static void clear_test(IDirect3DDevice9 *device)
434 {
435     /* Tests the correctness of clearing parameters */
436     HRESULT hr;
437     D3DRECT rect[2];
438     D3DRECT rect_negneg;
439     DWORD color;
440     D3DVIEWPORT9 old_vp, vp;
441     RECT scissor;
442     DWORD oldColorWrite;
443     BOOL invalid_clear_failed = FALSE;
444
445     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
447
448     /* Positive x, negative y */
449     rect[0].x1 = 0;
450     rect[0].y1 = 480;
451     rect[0].x2 = 320;
452     rect[0].y2 = 240;
453
454     /* Positive x, positive y */
455     rect[1].x1 = 0;
456     rect[1].y1 = 0;
457     rect[1].x2 = 320;
458     rect[1].y2 = 240;
459     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460      * returns D3D_OK, but ignores the rectangle silently
461      */
462     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465
466     /* negative x, negative y */
467     rect_negneg.x1 = 640;
468     rect_negneg.y1 = 240;
469     rect_negneg.x2 = 320;
470     rect_negneg.y2 = 0;
471     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
474
475     color = getPixelColor(device, 160, 360); /* lower left quad */
476     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477     color = getPixelColor(device, 160, 120); /* upper left quad */
478     if(invalid_clear_failed) {
479         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481     } else {
482         /* If the negative rectangle was dropped silently, the correct ones are cleared */
483         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
484     }
485     color = getPixelColor(device, 480, 360); /* lower right quad  */
486     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487     color = getPixelColor(device, 480, 120); /* upper right quad */
488     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
489
490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
491
492     /* Test how the viewport affects clears */
493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
497
498     vp.X = 160;
499     vp.Y = 120;
500     vp.Width = 160;
501     vp.Height = 120;
502     vp.MinZ = 0.0;
503     vp.MaxZ = 1.0;
504     hr = IDirect3DDevice9_SetViewport(device, &vp);
505     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     vp.X = 320;
510     vp.Y = 240;
511     vp.Width = 320;
512     vp.Height = 240;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     rect[0].x1 = 160;
518     rect[0].y1 = 120;
519     rect[0].x2 = 480;
520     rect[0].y2 = 360;
521     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523
524     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
526
527     color = getPixelColor(device, 158, 118);
528     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529     color = getPixelColor(device, 162, 118);
530     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531     color = getPixelColor(device, 158, 122);
532     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533     color = getPixelColor(device, 162, 122);
534     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
535
536     color = getPixelColor(device, 318, 238);
537     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538     color = getPixelColor(device, 322, 238);
539     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540     color = getPixelColor(device, 318, 242);
541     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542     color = getPixelColor(device, 322, 242);
543     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
544
545     color = getPixelColor(device, 478, 358);
546     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547     color = getPixelColor(device, 482, 358);
548     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549     color = getPixelColor(device, 478, 362);
550     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551     color = getPixelColor(device, 482, 362);
552     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
553
554     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
555
556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
558
559     scissor.left = 160;
560     scissor.right = 480;
561     scissor.top = 120;
562     scissor.bottom = 360;
563     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
567
568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
572
573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
575
576     color = getPixelColor(device, 158, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 162, 118);
579     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 158, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 162, 122);
583     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 158, 358);
586     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587     color = getPixelColor(device, 162, 358);
588     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589     color = getPixelColor(device, 158, 358);
590     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591     color = getPixelColor(device, 162, 362);
592     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
593
594     color = getPixelColor(device, 478, 118);
595     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596     color = getPixelColor(device, 478, 122);
597     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598     color = getPixelColor(device, 482, 122);
599     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600     color = getPixelColor(device, 482, 358);
601     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
602
603     color = getPixelColor(device, 478, 358);
604     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605     color = getPixelColor(device, 478, 362);
606     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607     color = getPixelColor(device, 482, 358);
608     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609     color = getPixelColor(device, 482, 362);
610     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
611
612     color = getPixelColor(device, 318, 238);
613     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614     color = getPixelColor(device, 318, 242);
615     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616     color = getPixelColor(device, 322, 238);
617     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618     color = getPixelColor(device, 322, 242);
619     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
620
621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622
623     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
627
628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Colorwriteenable does not affect the clear */
635     color = getPixelColor(device, 320, 240);
636     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
637
638     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639 }
640
641 static void color_fill_test(IDirect3DDevice9 *device)
642 {
643     HRESULT hr;
644     IDirect3DSurface9 *backbuffer = NULL;
645     IDirect3DSurface9 *rt_surface = NULL;
646     IDirect3DSurface9 *offscreen_surface = NULL;
647     DWORD fill_color, color;
648
649     /* Test ColorFill on a the backbuffer (should pass) */
650     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652     if(backbuffer)
653     {
654         fill_color = 0x112233;
655         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
656
657         color = getPixelColor(device, 0, 0);
658         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
659
660         IDirect3DSurface9_Release(backbuffer);
661     }
662
663     /* Test ColorFill on a render target surface (should pass) */
664     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666     if(rt_surface)
667     {
668         fill_color = 0x445566;
669         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
670
671         color = getPixelColorFromSurface(rt_surface, 0, 0);
672         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
673
674         IDirect3DSurface9_Release(rt_surface);
675     }
676
677     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681     if(offscreen_surface)
682     {
683         fill_color = 0x778899;
684         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
685
686         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
688
689         IDirect3DSurface9_Release(offscreen_surface);
690     }
691
692     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693     offscreen_surface = NULL;
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697     if(offscreen_surface)
698     {
699         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704 }
705
706 typedef struct {
707     float in[4];
708     DWORD out;
709 } test_data_t;
710
711 /*
712  *  c7      mova    ARGB            mov     ARGB
713  * -2.4     -2      0x00ffff00      -3      0x00ff0000
714  * -1.6     -2      0x00ffff00      -2      0x00ffff00
715  * -0.4      0      0x0000ffff      -1      0x0000ff00
716  *  0.4      0      0x0000ffff       0      0x0000ffff
717  *  1.6      2      0x00ff00ff       1      0x000000ff
718  *  2.4      2      0x00ff00ff       2      0x00ff00ff
719  */
720 static void test_mova(IDirect3DDevice9 *device)
721 {
722     static const DWORD mova_test[] = {
723         0xfffe0200,                                                             /* vs_2_0                       */
724         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
725         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
726         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
729         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
732         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
733         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
734         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
735         0x0000ffff                                                              /* END                          */
736     };
737     static const DWORD mov_test[] = {
738         0xfffe0101,                                                             /* vs_1_1                       */
739         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
740         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
741         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
744         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
747         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
748         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
749         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
750         0x0000ffff                                                              /* END                          */
751     };
752
753     static const test_data_t test_data[2][6] = {
754         {
755             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
761         },
762         {
763             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
769         }
770     };
771
772     static const float quad[][3] = {
773         {-1.0f, -1.0f, 0.0f},
774         {-1.0f,  1.0f, 0.0f},
775         { 1.0f, -1.0f, 0.0f},
776         { 1.0f,  1.0f, 0.0f},
777     };
778
779     static const D3DVERTEXELEMENT9 decl_elements[] = {
780         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781         D3DDECL_END()
782     };
783
784     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785     IDirect3DVertexShader9 *mova_shader = NULL;
786     IDirect3DVertexShader9 *mov_shader = NULL;
787     HRESULT hr;
788     UINT i, j;
789
790     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
798
799     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801     for(j = 0; j < 2; ++j)
802     {
803         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
804         {
805             DWORD color;
806
807             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
809
810             hr = IDirect3DDevice9_BeginScene(device);
811             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
812
813             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
815
816             hr = IDirect3DDevice9_EndScene(device);
817             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
818
819             color = getPixelColor(device, 320, 240);
820             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
822
823             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
828         }
829         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
831     }
832
833     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
835
836     IDirect3DVertexDeclaration9_Release(vertex_declaration);
837     IDirect3DVertexShader9_Release(mova_shader);
838     IDirect3DVertexShader9_Release(mov_shader);
839 }
840
841 struct sVertex {
842     float x, y, z;
843     DWORD diffuse;
844     DWORD specular;
845 };
846
847 struct sVertexT {
848     float x, y, z, rhw;
849     DWORD diffuse;
850     DWORD specular;
851 };
852
853 static void fog_test(IDirect3DDevice9 *device)
854 {
855     HRESULT hr;
856     D3DCOLOR color;
857     float start = 0.0f, end = 1.0f;
858     D3DCAPS9 caps;
859     int i;
860
861     /* Gets full z based fog with linear fog, no fog with specular color */
862     struct sVertex unstransformed_1[] = {
863         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
864         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
865         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
867     };
868     /* Ok, I am too lazy to deal with transform matrices */
869     struct sVertex unstransformed_2[] = {
870         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
871         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
872         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
874     };
875     /* Untransformed ones. Give them a different diffuse color to make the test look
876      * nicer. It also makes making sure that they are drawn correctly easier.
877      */
878     struct sVertexT transformed_1[] = {
879         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
880         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883     };
884     struct sVertexT transformed_2[] = {
885         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
886         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889     };
890     struct vertex rev_fog_quads[] = {
891        {-1.0,   -1.0,   0.1,    0x000000ff},
892        {-1.0,    0.0,   0.1,    0x000000ff},
893        { 0.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,   -1.0,   0.1,    0x000000ff},
895
896        { 0.0,   -1.0,   0.9,    0x000000ff},
897        { 0.0,    0.0,   0.9,    0x000000ff},
898        { 1.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,   -1.0,   0.9,    0x000000ff},
900
901        { 0.0,    0.0,   0.4,    0x000000ff},
902        { 0.0,    1.0,   0.4,    0x000000ff},
903        { 1.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    0.0,   0.4,    0x000000ff},
905
906        {-1.0,    0.0,   0.7,    0x000000ff},
907        {-1.0,    1.0,   0.7,    0x000000ff},
908        { 0.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    0.0,   0.7,    0x000000ff},
910     };
911     WORD Indices[] = {0, 1, 2, 2, 3, 0};
912
913     memset(&caps, 0, sizeof(caps));
914     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
918
919     /* Setup initial states: No lighting, fog on, fog color */
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
926
927     /* First test: Both table fog and vertex fog off */
928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
932
933     /* Start = 0, end = 1. Should be default, but set them */
934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
938
939     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
940     {
941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946                                                      sizeof(unstransformed_1[0]));
947         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
948
949         /* That makes it use the Z value */
950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952         /* Untransformed, vertex fog != none (or table fog != none):
953          * Use the Z value as input into the equation
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957                                                      sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959
960         /* transformed verts */
961         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966                                                      sizeof(transformed_1[0]));
967         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
968
969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972          * equation
973          */
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976                                                      sizeof(transformed_2[0]));
977         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
978
979         hr = IDirect3DDevice9_EndScene(device);
980         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
981     }
982     else
983     {
984         ok(FALSE, "BeginScene failed\n");
985     }
986
987     color = getPixelColor(device, 160, 360);
988     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989     color = getPixelColor(device, 160, 120);
990     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991     color = getPixelColor(device, 480, 120);
992     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
994     {
995         color = getPixelColor(device, 480, 360);
996         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
997     }
998     else
999     {
1000         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001          * The settings above result in no fogging with vertex fog
1002          */
1003         color = getPixelColor(device, 480, 120);
1004         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005         trace("Info: Table fog not supported by this device\n");
1006     }
1007     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1008
1009     /* Now test the special case fogstart == fogend */
1010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1012
1013     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1014     {
1015         start = 512;
1016         end = 512;
1017         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1021
1022         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1028
1029         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033          * color and has fixed fogstart and fogend.
1034          */
1035         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037                 sizeof(unstransformed_1[0]));
1038         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041                 sizeof(unstransformed_1[0]));
1042         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1043
1044         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049                 sizeof(transformed_1[0]));
1050         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1051
1052         hr = IDirect3DDevice9_EndScene(device);
1053         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1054     }
1055     else
1056     {
1057         ok(FALSE, "BeginScene failed\n");
1058     }
1059     color = getPixelColor(device, 160, 360);
1060     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061     color = getPixelColor(device, 160, 120);
1062     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063     color = getPixelColor(device, 480, 120);
1064     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066
1067     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068      * but without shaders it seems to work everywhere
1069      */
1070     end = 0.2;
1071     start = 0.8;
1072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1078
1079     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081      * so skip this for now
1082      */
1083     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084         const char *mode = (i ? "table" : "vertex");
1085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091         hr = IDirect3DDevice9_BeginScene(device);
1092         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093         if(SUCCEEDED(hr)) {
1094             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1095                                 4,  5,  6,  6,  7, 4,
1096                                 8,  9, 10, 10, 11, 8,
1097                             12, 13, 14, 14, 15, 12};
1098
1099             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101                     sizeof(rev_fog_quads[0]));
1102             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1103
1104             hr = IDirect3DDevice9_EndScene(device);
1105             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1106         }
1107         color = getPixelColor(device, 160, 360);
1108         ok(color_match(color, 0x0000ff00, 1),
1109                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1110
1111         color = getPixelColor(device, 160, 120);
1112         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1114
1115         color = getPixelColor(device, 480, 120);
1116         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1118
1119         color = getPixelColor(device, 480, 360);
1120         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1121
1122         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1123
1124         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126             break;
1127         }
1128     }
1129     /* Turn off the fog master switch to avoid confusing other tests */
1130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132     start = 0.0;
1133     end = 1.0;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 }
1143
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146  * regardless of the actual addressing mode set. The way this test works is
1147  * that we sample in one of the corners of the cubemap with filtering enabled,
1148  * and check the interpolated color. There are essentially two reasonable
1149  * things an implementation can do: Either pick one of the faces and
1150  * interpolate the edge texel with itself (i.e., clamp within the face), or
1151  * interpolate between the edge texels of the three involved faces. It should
1152  * never involve the border color or the other side (texcoord wrapping) of a
1153  * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1155 {
1156     static const float quad[][6] = {
1157         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161     };
1162
1163     static const D3DVERTEXELEMENT9 decl_elements[] = {
1164         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166         D3DDECL_END()
1167     };
1168
1169     static const struct {
1170         D3DTEXTUREADDRESS mode;
1171         const char *name;
1172     } address_modes[] = {
1173         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1178     };
1179
1180     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181     IDirect3DCubeTexture9 *texture = NULL;
1182     IDirect3DSurface9 *surface = NULL;
1183     IDirect3DSurface9 *face_surface;
1184     D3DLOCKED_RECT locked_rect;
1185     HRESULT hr;
1186     UINT x;
1187     INT y, face;
1188
1189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1193
1194     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1197
1198     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199             D3DPOOL_DEFAULT, &texture, NULL);
1200     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1201
1202     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1204
1205     for (y = 0; y < 128; ++y)
1206     {
1207         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208         for (x = 0; x < 64; ++x)
1209         {
1210             *ptr++ = 0xff0000ff;
1211         }
1212         for (x = 64; x < 128; ++x)
1213         {
1214             *ptr++ = 0xffff0000;
1215         }
1216     }
1217
1218     hr = IDirect3DSurface9_UnlockRect(surface);
1219     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1220
1221     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1223
1224     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1226
1227     IDirect3DSurface9_Release(face_surface);
1228
1229     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1231
1232     for (y = 0; y < 128; ++y)
1233     {
1234         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235         for (x = 0; x < 64; ++x)
1236         {
1237             *ptr++ = 0xffff0000;
1238         }
1239         for (x = 64; x < 128; ++x)
1240         {
1241             *ptr++ = 0xff0000ff;
1242         }
1243     }
1244
1245     hr = IDirect3DSurface9_UnlockRect(surface);
1246     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1247
1248     /* Create cube faces */
1249     for (face = 1; face < 6; ++face)
1250     {
1251         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1253
1254         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1256
1257         IDirect3DSurface9_Release(face_surface);
1258     }
1259
1260     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1262
1263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1269
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1274     {
1275         DWORD color;
1276
1277         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1281
1282         hr = IDirect3DDevice9_BeginScene(device);
1283         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1284
1285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1287
1288         hr = IDirect3DDevice9_EndScene(device);
1289         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1290
1291         color = getPixelColor(device, 320, 240);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294                 color, address_modes[x].name);
1295
1296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1298
1299         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1301     }
1302
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1305
1306     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307     IDirect3DCubeTexture9_Release(texture);
1308     IDirect3DSurface9_Release(surface);
1309 }
1310
1311 static void offscreen_test(IDirect3DDevice9 *device)
1312 {
1313     HRESULT hr;
1314     IDirect3DTexture9 *offscreenTexture = NULL;
1315     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316     DWORD color;
1317
1318     static const float quad[][5] = {
1319         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1321         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1323     };
1324
1325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1327
1328     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330     if(!offscreenTexture) {
1331         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334         if(!offscreenTexture) {
1335             skip("Cannot create an offscreen render target\n");
1336             goto out;
1337         }
1338     }
1339
1340     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342     if(!backbuffer) {
1343         goto out;
1344     }
1345
1346     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348     if(!offscreen) {
1349         goto out;
1350     }
1351
1352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1354
1355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1365
1366     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1371
1372         /* Draw without textures - Should result in a white quad */
1373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1375
1376         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1380
1381         /* This time with the texture */
1382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1384
1385         IDirect3DDevice9_EndScene(device);
1386     }
1387
1388     /* Center quad - should be white */
1389     color = getPixelColor(device, 320, 240);
1390     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391     /* Some quad in the cleared part of the texture */
1392     color = getPixelColor(device, 170, 240);
1393     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394     /* Part of the originally cleared back buffer */
1395     color = getPixelColor(device, 10, 10);
1396     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397     if(0) {
1398         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400          * the offscreen rendering mode this test would succeed or fail
1401          */
1402         color = getPixelColor(device, 10, 470);
1403         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1404     }
1405
1406     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1407
1408 out:
1409     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1411
1412     /* restore things */
1413     if(backbuffer) {
1414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416         IDirect3DSurface9_Release(backbuffer);
1417     }
1418     if(offscreenTexture) {
1419         IDirect3DTexture9_Release(offscreenTexture);
1420     }
1421     if(offscreen) {
1422         IDirect3DSurface9_Release(offscreen);
1423     }
1424 }
1425
1426 /* This test tests fog in combination with shaders.
1427  * What's tested: linear fog (vertex and table) with pixel shader
1428  *                linear table fog with non foggy vertex shader
1429  *                vertex fog with foggy vertex shader, non-linear
1430  *                fog with shader, non-linear fog with foggy shader,
1431  *                linear table fog with foggy shader
1432  */
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1434 {
1435     HRESULT hr;
1436     DWORD color;
1437     union {
1438         float f;
1439         DWORD i;
1440     } start, end;
1441     unsigned int i, j;
1442
1443     /* basic vertex shader without fog computation ("non foggy") */
1444     static const DWORD vertex_shader_code1[] = {
1445         0xfffe0101,                                                             /* vs_1_1                       */
1446         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1447         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1448         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1449         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1450         0x0000ffff
1451     };
1452     /* basic vertex shader with reversed fog computation ("foggy") */
1453     static const DWORD vertex_shader_code2[] = {
1454         0xfffe0101,                                                             /* vs_1_1                        */
1455         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1456         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1457         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1459         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1460         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1461         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1462         0x0000ffff
1463     };
1464     /* basic pixel shader */
1465     static const DWORD pixel_shader_code[] = {
1466         0xffff0101,                                                             /* ps_1_1     */
1467         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1468         0x0000ffff
1469     };
1470
1471     static struct vertex quad[] = {
1472         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1473         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1474         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1476     };
1477
1478     static const D3DVERTEXELEMENT9 decl_elements[] = {
1479         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1481         D3DDECL_END()
1482     };
1483
1484     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1486     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1487
1488     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489     static const struct test_data_t {
1490         int vshader;
1491         int pshader;
1492         D3DFOGMODE vfog;
1493         D3DFOGMODE tfog;
1494         unsigned int color[11];
1495     } test_data[] = {
1496         /* only pixel shader: */
1497         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512
1513         /* vertex shader */
1514         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523
1524         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader and pixel shader */
1532         /* The next 4 tests would read the fog coord output, but it isn't available.
1533          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535          * These tests should be disabled if some other hardware behaves differently
1536          */
1537         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1549
1550         /* These use the Z coordinate with linear table fog */
1551         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1563
1564         /* Non-linear table fog without fog coord */
1565         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1571
1572 #if 0  /* FIXME: these fail on GeForce 8500 */
1573         /* foggy vertex shader */
1574         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1587
1588         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589          * all using the fixed fog-coord linear fog
1590          */
1591         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1603
1604         /* These use table fog. Here the shader-provided fog coordinate is
1605          * ignored and the z coordinate used instead
1606          */
1607         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1616     };
1617
1618     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619     start.f=0.1f;
1620     end.f=0.9f;
1621
1622     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1630
1631     /* Setup initial states: No lighting, fog on, fog color */
1632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1640
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1645
1646     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1651
1652     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1653     {
1654         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1662
1663         for(j=0; j < 11; j++)
1664         {
1665             /* Don't use the whole zrange to prevent rounding errors */
1666             quad[0].z = 0.001f + (float)j / 10.02f;
1667             quad[1].z = 0.001f + (float)j / 10.02f;
1668             quad[2].z = 0.001f + (float)j / 10.02f;
1669             quad[3].z = 0.001f + (float)j / 10.02f;
1670
1671             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1673
1674             hr = IDirect3DDevice9_BeginScene(device);
1675             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1676
1677             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679
1680             hr = IDirect3DDevice9_EndScene(device);
1681             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1682
1683             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684             color = getPixelColor(device, 128, 240);
1685             ok(color_match(color, test_data[i].color[j], 13),
1686                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1688
1689             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1690         }
1691     }
1692
1693     /* reset states */
1694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1702
1703     IDirect3DVertexShader9_Release(vertex_shader[1]);
1704     IDirect3DVertexShader9_Release(vertex_shader[2]);
1705     IDirect3DPixelShader9_Release(pixel_shader[1]);
1706     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1707 }
1708
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710     unsigned int i, x, y;
1711     HRESULT hr;
1712     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713     D3DLOCKED_RECT locked_rect;
1714
1715     /* Generate the textures */
1716     for(i=0; i<2; i++)
1717     {
1718         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719                                             D3DPOOL_MANAGED, &texture[i], NULL);
1720         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1721
1722         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724         for (y = 0; y < 128; ++y)
1725         {
1726             if(i)
1727             { /* Set up black texture with 2x2 texel white spot in the middle */
1728                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729                 for (x = 0; x < 128; ++x)
1730                 {
1731                     if(y>62 && y<66 && x>62 && x<66)
1732                         *ptr++ = 0xffffffff;
1733                     else
1734                         *ptr++ = 0xff000000;
1735                 }
1736             }
1737             else
1738             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739                * (if multiplied with bumpenvmat)
1740               */
1741                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(abs(x-64)>abs(y-64))
1745                     {
1746                         if(x < 64)
1747                             *ptr++ = 0xc000;
1748                         else
1749                             *ptr++ = 0x4000;
1750                     }
1751                     else
1752                     {
1753                         if(y < 64)
1754                             *ptr++ = 0x0040;
1755                         else
1756                             *ptr++ = 0x00c0;
1757                     }
1758                 }
1759             }
1760         }
1761         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1763
1764         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1766
1767         /* Disable texture filtering */
1768         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1772
1773         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1777     }
1778 }
1779
1780 /* test the behavior of the texbem instruction
1781  * with normal 2D and projective 2D textures
1782  */
1783 static void texbem_test(IDirect3DDevice9 *device)
1784 {
1785     HRESULT hr;
1786     DWORD color;
1787     int i;
1788
1789     static const DWORD pixel_shader_code[] = {
1790         0xffff0101,                         /* ps_1_1*/
1791         0x00000042, 0xb00f0000,             /* tex t0*/
1792         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794         0x0000ffff
1795     };
1796     static const DWORD double_texbem_code[] =  {
1797         0xffff0103,                                         /* ps_1_3           */
1798         0x00000042, 0xb00f0000,                             /* tex t0           */
1799         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1800         0x00000042, 0xb00f0002,                             /* tex t2           */
1801         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1802         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1803         0x0000ffff                                          /* end              */
1804     };
1805
1806
1807     static const float quad[][7] = {
1808         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1812     };
1813     static const float quad_proj[][9] = {
1814         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1815         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1816         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1818     };
1819
1820     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824         D3DDECL_END()
1825     },{
1826         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829         D3DDECL_END()
1830     } };
1831
1832     /* use asymmetric matrix to test loading */
1833     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1834
1835     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836     IDirect3DPixelShader9       *pixel_shader       = NULL;
1837     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1838     D3DLOCKED_RECT locked_rect;
1839
1840     generate_bumpmap_textures(device);
1841
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1847
1848     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1850
1851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1853
1854     for(i=0; i<2; i++)
1855     {
1856         if(i)
1857         {
1858             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1860         }
1861
1862         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1866
1867         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1871
1872         hr = IDirect3DDevice9_BeginScene(device);
1873         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874
1875         if(!i)
1876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877         else
1878             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1880
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883
1884         color = getPixelColor(device, 320-32, 240);
1885         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886         color = getPixelColor(device, 320+32, 240);
1887         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888         color = getPixelColor(device, 320, 240-32);
1889         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890         color = getPixelColor(device, 320, 240+32);
1891         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1895
1896         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898         IDirect3DPixelShader9_Release(pixel_shader);
1899
1900         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1903     }
1904
1905     /* clean up */
1906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1911
1912     for(i=0; i<2; i++)
1913     {
1914         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919         IDirect3DTexture9_Release(texture);
1920     }
1921
1922     /* Test double texbem */
1923     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1931
1932     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1936
1937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1939
1940     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1946
1947     {
1948         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex  0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952         static const DWORD pixel_data[] = {
1953             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961         };
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1965
1966         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968         for(i = 0; i < 8; i++) {
1969             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1970         }
1971         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1973     }
1974
1975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1987
1988     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1989     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1998
1999     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2000     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2001     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009
2010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2026
2027     hr = IDirect3DDevice9_BeginScene(device);
2028     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029     if(SUCCEEDED(hr)) {
2030         static const float double_quad[] = {
2031             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2032              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035         };
2036
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039         hr = IDirect3DDevice9_EndScene(device);
2040         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2041     }
2042     color = getPixelColor(device, 320, 240);
2043     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2044
2045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2055
2056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058
2059     IDirect3DPixelShader9_Release(pixel_shader);
2060     IDirect3DTexture9_Release(texture);
2061     IDirect3DTexture9_Release(texture1);
2062     IDirect3DTexture9_Release(texture2);
2063 }
2064
2065 static void z_range_test(IDirect3DDevice9 *device)
2066 {
2067     const struct vertex quad[] =
2068     {
2069         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2070         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2071         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2072         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2073     };
2074     const struct vertex quad2[] =
2075     {
2076         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2077         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2078         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2079         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2080     };
2081
2082     const struct tvertex quad3[] =
2083     {
2084         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2085         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2086         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2087         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2088     };
2089     const struct tvertex quad4[] =
2090     {
2091         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2092         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2093         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2094         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2095     };
2096     HRESULT hr;
2097     DWORD color;
2098     IDirect3DVertexShader9 *shader;
2099     IDirect3DVertexDeclaration9 *decl;
2100     D3DCAPS9 caps;
2101     const DWORD shader_code[] = {
2102         0xfffe0101,                                     /* vs_1_1           */
2103         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2104         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2105         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2106         0x0000ffff                                      /* end              */
2107     };
2108     static const D3DVERTEXELEMENT9 decl_elements[] = {
2109         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110         D3DDECL_END()
2111     };
2112     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113      * then call Present. Then clear the color buffer to make sure it has some defined content
2114      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115      * by the depth value.
2116      */
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2123
2124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2134
2135     hr = IDirect3DDevice9_BeginScene(device);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137     if(hr == D3D_OK)
2138     {
2139         /* Test the untransformed vertex path */
2140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2146
2147         /* Test the transformed vertex path */
2148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2157
2158         hr = IDirect3DDevice9_EndScene(device);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2160     }
2161
2162     /* Do not test the exact corner pixels, but go pretty close to them */
2163
2164     /* Clipped because z > 1.0 */
2165     color = getPixelColor(device, 28, 238);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167     color = getPixelColor(device, 28, 241);
2168     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2169
2170     /* Not clipped, > z buffer clear value(0.75) */
2171     color = getPixelColor(device, 31, 238);
2172     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173     color = getPixelColor(device, 31, 241);
2174     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175     color = getPixelColor(device, 100, 238);
2176     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177     color = getPixelColor(device, 100, 241);
2178     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2179
2180     /* Not clipped, < z buffer clear value */
2181     color = getPixelColor(device, 104, 238);
2182     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183     color = getPixelColor(device, 104, 241);
2184     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185     color = getPixelColor(device, 318, 238);
2186     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187     color = getPixelColor(device, 318, 241);
2188     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2189
2190     /* Clipped because z < 0.0 */
2191     color = getPixelColor(device, 321, 238);
2192     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193     color = getPixelColor(device, 321, 241);
2194     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2195
2196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2198
2199     /* Test the shader path */
2200     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202         skip("Vertex shaders not supported\n");
2203         goto out;
2204     }
2205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2209
2210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2211
2212     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214     IDirect3DDevice9_SetVertexShader(device, shader);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2216
2217     hr = IDirect3DDevice9_BeginScene(device);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219     if(hr == D3D_OK)
2220     {
2221         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2231
2232         hr = IDirect3DDevice9_EndScene(device);
2233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2234     }
2235
2236     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238     IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2240
2241     IDirect3DVertexDeclaration9_Release(decl);
2242     IDirect3DVertexShader9_Release(shader);
2243
2244     /* Z < 1.0 */
2245     color = getPixelColor(device, 28, 238);
2246     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2247
2248     /* 1.0 < z < 0.75 */
2249     color = getPixelColor(device, 31, 238);
2250     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251     color = getPixelColor(device, 100, 238);
2252     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2253
2254     /* 0.75 < z < 0.0 */
2255     color = getPixelColor(device, 104, 238);
2256     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257     color = getPixelColor(device, 318, 238);
2258     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2259
2260     /* 0.0 < z */
2261     color = getPixelColor(device, 321, 238);
2262     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2263
2264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2266
2267     out:
2268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2274 }
2275
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2277 {
2278     D3DSURFACE_DESC desc;
2279     D3DLOCKED_RECT l;
2280     HRESULT hr;
2281     unsigned int x, y;
2282     DWORD *mem;
2283
2284     memset(&desc, 0, sizeof(desc));
2285     memset(&l, 0, sizeof(l));
2286     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290     if(FAILED(hr)) return;
2291
2292     for(y = 0; y < desc.Height; y++)
2293     {
2294         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2296         {
2297             mem[x] = color;
2298         }
2299     }
2300     hr = IDirect3DSurface9_UnlockRect(surface);
2301     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2302 }
2303
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2306 {
2307     HRESULT hr;
2308     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315     IDirect3DSurface9 *orig_rt = NULL;
2316     IDirect3DSurface9 *backbuffer = NULL;
2317     DWORD color;
2318
2319     RECT src_rect64 = {0, 0, 64, 64};
2320     RECT src_rect64_flipy = {0, 64, 64, 0};
2321     RECT dst_rect64 = {0, 0, 64, 64};
2322     RECT dst_rect64_flipy = {0, 64, 64, 0};
2323
2324     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326     if(!orig_rt) {
2327         goto out;
2328     }
2329
2330     /* Create our temporary surfaces in system memory */
2331     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2335
2336     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2343
2344     /* Create render target surfaces */
2345     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2353
2354     /* Create render target textures */
2355     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363     if (tex_rt32) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_rt64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371     if (tex_rt_dest64) {
2372         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2374     }
2375     if (tex_rt_dest64) {
2376         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2378     }
2379
2380     /* Create regular textures in D3DPOOL_DEFAULT */
2381     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387     if (tex32) {
2388         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2390     }
2391     if (tex64) {
2392         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2394     }
2395     if (tex_dest64) {
2396         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398     }
2399
2400     /*********************************************************************
2401      * Tests for when the source parameter is an offscreen plain surface *
2402      *********************************************************************/
2403
2404     /* Fill the offscreen 64x64 surface with green */
2405     if (surf_offscreen64)
2406         fill_surface(surf_offscreen64, 0xff00ff00);
2407
2408     /* offscreenplain ==> offscreenplain, same size */
2409     if(surf_offscreen64 && surf_offscreen_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2416         }
2417
2418         /* Blit without scaling */
2419         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421
2422         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425
2426         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429     }
2430
2431     /* offscreenplain ==> rendertarget texture, same size */
2432     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         /* We can't lock rendertarget textures, so copy to our temp surface first */
2437         if (hr == D3D_OK) {
2438             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2440         }
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget surface, same size */
2461     if(surf_offscreen64 && surf_rt_dest64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         if (hr == D3D_OK) {
2466             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2468         }
2469
2470         /* Blit without scaling */
2471         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473
2474         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481     }
2482
2483     /* offscreenplain ==> texture, same size (should fail) */
2484     if(surf_offscreen64 && surf_tex_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2487     }
2488
2489     /* Fill the smaller offscreen surface with red */
2490     fill_surface(surf_offscreen32, 0xffff0000);
2491
2492     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493     if(surf_offscreen32 && surf_offscreen64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* offscreenplain ==> rendertarget texture, scaling */
2499     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* We can't lock rendertarget textures, so copy to our temp surface first */
2504         if (hr == D3D_OK) {
2505             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2507         }
2508
2509         if (hr == D3D_OK) {
2510             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512         }
2513     }
2514
2515     /* offscreenplain ==> rendertarget surface, scaling */
2516     if(surf_offscreen32 && surf_rt_dest64) {
2517         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519
2520         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2522     }
2523
2524     /* offscreenplain ==> texture, scaling (should fail) */
2525     if(surf_offscreen32 && surf_tex_dest64) {
2526         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2528     }
2529
2530     /************************************************************
2531      * Tests for when the source parameter is a regular texture *
2532      ************************************************************/
2533
2534     /* Fill the surface of the regular texture with blue */
2535     if (surf_tex64 && surf_temp64) {
2536         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537         fill_surface(surf_temp64, 0xff0000ff);
2538         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2540     }
2541
2542     /* texture ==> offscreenplain, same size */
2543     if(surf_tex64 && surf_offscreen64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /* texture ==> rendertarget texture, same size */
2549     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         /* We can't lock rendertarget textures, so copy to our temp surface first */
2554         if (hr == D3D_OK) {
2555             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2557         }
2558
2559         if (hr == D3D_OK) {
2560             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2562         }
2563
2564         /* Blit without scaling */
2565         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571
2572         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575     }
2576
2577     /* texture ==> rendertarget surface, same size */
2578     if(surf_tex64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2585         }
2586
2587         /* Blit without scaling */
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590
2591         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594
2595         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2598     }
2599
2600     /* texture ==> texture, same size (should fail) */
2601     if(surf_tex64 && surf_tex_dest64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604     }
2605
2606     /* Fill the surface of the smaller regular texture with red */
2607     if (surf_tex32 && surf_temp32) {
2608         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609         fill_surface(surf_temp32, 0xffff0000);
2610         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2612     }
2613
2614     /* texture ==> offscreenplain, scaling (should fail) */
2615     if(surf_tex32 && surf_offscreen64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2618     }
2619
2620     /* texture ==> rendertarget texture, scaling */
2621     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* We can't lock rendertarget textures, so copy to our temp surface first */
2626         if (hr == D3D_OK) {
2627             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2629         }
2630
2631         if (hr == D3D_OK) {
2632             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634         }
2635     }
2636
2637     /* texture ==> rendertarget surface, scaling */
2638     if(surf_tex32 && surf_rt_dest64) {
2639         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2644     }
2645
2646     /* texture ==> texture, scaling (should fail) */
2647     if(surf_tex32 && surf_tex_dest64) {
2648         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2650     }
2651
2652     /*****************************************************************
2653      * Tests for when the source parameter is a rendertarget texture *
2654      *****************************************************************/
2655
2656     /* Fill the surface of the rendertarget texture with white */
2657     if (surf_tex_rt64 && surf_temp64) {
2658         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659         fill_surface(surf_temp64, 0xffffffff);
2660         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2662     }
2663
2664     /* rendertarget texture ==> offscreenplain, same size */
2665     if(surf_tex_rt64 && surf_offscreen64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /* rendertarget texture ==> rendertarget texture, same size */
2671     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2674
2675         /* We can't lock rendertarget textures, so copy to our temp surface first */
2676         if (hr == D3D_OK) {
2677             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2679         }
2680
2681         if (hr == D3D_OK) {
2682             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2684         }
2685
2686         /* Blit without scaling */
2687         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689
2690         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693
2694         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697     }
2698
2699     /* rendertarget texture ==> rendertarget surface, same size */
2700     if(surf_tex_rt64 && surf_rt_dest64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         if (hr == D3D_OK) {
2705             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2707         }
2708
2709         /* Blit without scaling */
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712
2713         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2716
2717         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720     }
2721
2722     /* rendertarget texture ==> texture, same size (should fail) */
2723     if(surf_tex_rt64 && surf_tex_dest64) {
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2726     }
2727
2728     /* Fill the surface of the smaller rendertarget texture with red */
2729     if (surf_tex_rt32 && surf_temp32) {
2730         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731         fill_surface(surf_temp32, 0xffff0000);
2732         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2734     }
2735
2736     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737     if(surf_tex_rt32 && surf_offscreen64) {
2738         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2740     }
2741
2742     /* rendertarget texture ==> rendertarget texture, scaling */
2743     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* We can't lock rendertarget textures, so copy to our temp surface first */
2748         if (hr == D3D_OK) {
2749             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2751         }
2752
2753         if (hr == D3D_OK) {
2754             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2756         }
2757     }
2758
2759     /* rendertarget texture ==> rendertarget surface, scaling */
2760     if(surf_tex_rt32 && surf_rt_dest64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763
2764         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2766     }
2767
2768     /* rendertarget texture ==> texture, scaling (should fail) */
2769     if(surf_tex_rt32 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /*****************************************************************
2775      * Tests for when the source parameter is a rendertarget surface *
2776      *****************************************************************/
2777
2778     /* Fill the surface of the rendertarget surface with black */
2779     if (surf_rt64)
2780         fill_surface(surf_rt64, 0xff000000);
2781
2782     /* rendertarget texture ==> offscreenplain, same size */
2783     if(surf_rt64 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* rendertarget surface ==> rendertarget texture, same size */
2789     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         /* We can't lock rendertarget textures, so copy to our temp surface first */
2794         if (hr == D3D_OK) {
2795             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2797         }
2798
2799         if (hr == D3D_OK) {
2800             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2802         }
2803
2804         /* Blit without scaling */
2805         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2807
2808         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811
2812         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815     }
2816
2817     /* rendertarget surface ==> rendertarget surface, same size */
2818     if(surf_rt64 && surf_rt_dest64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         if (hr == D3D_OK) {
2823             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2825         }
2826
2827         /* Blit without scaling */
2828         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830
2831         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838     }
2839
2840     /* rendertarget surface ==> texture, same size (should fail) */
2841     if(surf_rt64 && surf_tex_dest64) {
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2844     }
2845
2846     /* Fill the surface of the smaller rendertarget texture with red */
2847     if (surf_rt32)
2848         fill_surface(surf_rt32, 0xffff0000);
2849
2850     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851     if(surf_rt32 && surf_offscreen64) {
2852         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2854     }
2855
2856     /* rendertarget surface ==> rendertarget texture, scaling */
2857     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* We can't lock rendertarget textures, so copy to our temp surface first */
2862         if (hr == D3D_OK) {
2863             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2865         }
2866
2867         if (hr == D3D_OK) {
2868             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2870         }
2871     }
2872
2873     /* rendertarget surface ==> rendertarget surface, scaling */
2874     if(surf_rt32 && surf_rt_dest64) {
2875         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2877
2878         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2880     }
2881
2882     /* rendertarget surface ==> texture, scaling (should fail) */
2883     if(surf_rt32 && surf_tex_dest64) {
2884         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2886     }
2887
2888     /* backbuffer ==> surface tests (no scaling) */
2889     if(backbuffer && surf_tex_rt_dest640_480)
2890     {
2891         RECT src_rect = {0, 0, 640, 480};
2892         RECT src_rect_flipy = {0, 480, 640, 0};
2893         RECT dst_rect = {0, 0, 640, 480};
2894         RECT dst_rect_flipy = {0, 480, 640, 0};
2895
2896         /* Blit with NULL rectangles */
2897         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2899
2900         /* Blit without scaling */
2901         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2903
2904         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907
2908         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911     }
2912
2913     /* TODO: Test format conversions */
2914
2915
2916 out:
2917     /* Clean up */
2918     if (backbuffer)
2919         IDirect3DSurface9_Release(backbuffer);
2920     if (surf_rt32)
2921         IDirect3DSurface9_Release(surf_rt32);
2922     if (surf_rt64)
2923         IDirect3DSurface9_Release(surf_rt64);
2924     if (surf_rt_dest64)
2925         IDirect3DSurface9_Release(surf_rt_dest64);
2926     if (surf_temp32)
2927         IDirect3DSurface9_Release(surf_temp32);
2928     if (surf_temp64)
2929         IDirect3DSurface9_Release(surf_temp64);
2930     if (surf_offscreen32)
2931         IDirect3DSurface9_Release(surf_offscreen32);
2932     if (surf_offscreen64)
2933         IDirect3DSurface9_Release(surf_offscreen64);
2934     if (surf_offscreen_dest64)
2935         IDirect3DSurface9_Release(surf_offscreen_dest64);
2936
2937     if (tex_rt32) {
2938         if (surf_tex_rt32)
2939             IDirect3DSurface9_Release(surf_tex_rt32);
2940         IDirect3DTexture9_Release(tex_rt32);
2941     }
2942     if (tex_rt64) {
2943         if (surf_tex_rt64)
2944             IDirect3DSurface9_Release(surf_tex_rt64);
2945         IDirect3DTexture9_Release(tex_rt64);
2946     }
2947     if (tex_rt_dest64) {
2948         if (surf_tex_rt_dest64)
2949             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950         IDirect3DTexture9_Release(tex_rt_dest64);
2951     }
2952     if (tex_rt_dest640_480) {
2953         if (surf_tex_rt_dest640_480)
2954             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955         IDirect3DTexture9_Release(tex_rt_dest640_480);
2956     }
2957     if (tex32) {
2958         if (surf_tex32)
2959             IDirect3DSurface9_Release(surf_tex32);
2960         IDirect3DTexture9_Release(tex32);
2961     }
2962     if (tex64) {
2963         if (surf_tex64)
2964             IDirect3DSurface9_Release(surf_tex64);
2965         IDirect3DTexture9_Release(tex64);
2966     }
2967     if (tex_dest64) {
2968         if (surf_tex_dest64)
2969             IDirect3DSurface9_Release(surf_tex_dest64);
2970         IDirect3DTexture9_Release(tex_dest64);
2971     }
2972
2973     if (orig_rt) {
2974         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976         IDirect3DSurface9_Release(orig_rt);
2977     }
2978 }
2979
2980 static void maxmip_test(IDirect3DDevice9 *device)
2981 {
2982     IDirect3DTexture9 *texture = NULL;
2983     IDirect3DSurface9 *surface = NULL;
2984     HRESULT hr;
2985     DWORD color;
2986     const float quads[] = {
2987         -1.0,   -1.0,   0.0,    0.0,    0.0,
2988         -1.0,    0.0,   0.0,    0.0,    1.0,
2989          0.0,   -1.0,   0.0,    1.0,    0.0,
2990          0.0,    0.0,   0.0,    1.0,    1.0,
2991
2992          0.0,   -1.0,   0.0,    0.0,    0.0,
2993          0.0,    0.0,   0.0,    0.0,    1.0,
2994          1.0,   -1.0,   0.0,    1.0,    0.0,
2995          1.0,    0.0,   0.0,    1.0,    1.0,
2996
2997          0.0,    0.0,   0.0,    0.0,    0.0,
2998          0.0,    1.0,   0.0,    0.0,    1.0,
2999          1.0,    0.0,   0.0,    1.0,    0.0,
3000          1.0,    1.0,   0.0,    1.0,    1.0,
3001
3002         -1.0,    0.0,   0.0,    0.0,    0.0,
3003         -1.0,    1.0,   0.0,    0.0,    1.0,
3004          0.0,    0.0,   0.0,    1.0,    0.0,
3005          0.0,    1.0,   0.0,    1.0,    1.0,
3006     };
3007
3008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012                                         &texture, NULL);
3013     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014     if(!texture)
3015     {
3016         skip("Failed to create test texture\n");
3017         return;
3018     }
3019
3020     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022     fill_surface(surface, 0xffff0000);
3023     IDirect3DSurface9_Release(surface);
3024     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026     fill_surface(surface, 0xff00ff00);
3027     IDirect3DSurface9_Release(surface);
3028     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030     fill_surface(surface, 0xff0000ff);
3031     IDirect3DSurface9_Release(surface);
3032
3033     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3035     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3037
3038     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3040
3041     hr = IDirect3DDevice9_BeginScene(device);
3042     if(SUCCEEDED(hr))
3043     {
3044         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3048
3049         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3053
3054         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3058
3059         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063         hr = IDirect3DDevice9_EndScene(device);
3064         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3065     }
3066
3067     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068     color = getPixelColor(device, 160, 360);
3069     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070     color = getPixelColor(device, 160, 120);
3071     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072     color = getPixelColor(device, 480, 120);
3073     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074     color = getPixelColor(device, 480, 360);
3075     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3078
3079     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3081
3082     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     if(SUCCEEDED(hr))
3087     {
3088         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107         hr = IDirect3DDevice9_EndScene(device);
3108         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3109     }
3110
3111     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112      * samples from the highest level in the texture(level 2)
3113      */
3114     color = getPixelColor(device, 160, 360);
3115     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116     color = getPixelColor(device, 160, 120);
3117     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118     color = getPixelColor(device, 480, 120);
3119     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120     color = getPixelColor(device, 480, 360);
3121     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3124
3125     hr = IDirect3DDevice9_BeginScene(device);
3126     if(SUCCEEDED(hr))
3127     {
3128         DWORD ret;
3129
3130         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3134         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135         ret = IDirect3DTexture9_SetLOD(texture, 1);
3136         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145         ret = IDirect3DTexture9_SetLOD(texture, 2);
3146         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3149
3150         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153         ret = IDirect3DTexture9_SetLOD(texture, 1);
3154         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3157
3158         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163         ret = IDirect3DTexture9_SetLOD(texture, 1);
3164         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167         hr = IDirect3DDevice9_EndScene(device);
3168     }
3169
3170     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171      * samples from the highest level in the texture(level 2)
3172      */
3173     color = getPixelColor(device, 160, 360);
3174     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175     color = getPixelColor(device, 160, 120);
3176     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177     color = getPixelColor(device, 480, 120);
3178     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179     color = getPixelColor(device, 480, 360);
3180     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3183
3184     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190     IDirect3DTexture9_Release(texture);
3191 }
3192
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3194 {
3195     IDirect3DVertexBuffer9 *vb = NULL;
3196     IDirect3DIndexBuffer9 *ib = NULL;
3197     HRESULT hr;
3198     BYTE *data;
3199     LONG ref;
3200
3201     static const struct vertex quad[] = {
3202         {-1.0,      -1.0,       0.1,        0xffff0000},
3203         {-1.0,       1.0,       0.1,        0xffff0000},
3204         { 1.0,       1.0,       0.1,        0xffff0000},
3205
3206         {-1.0,      -1.0,       0.1,        0xff00ff00},
3207         {-1.0,       1.0,       0.1,        0xff00ff00},
3208         { 1.0,       1.0,       0.1,        0xff00ff00}
3209     };
3210     short indices[] = {3, 4, 5};
3211
3212     /* Index and vertex buffers should always be creatable */
3213     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214                                               D3DPOOL_MANAGED, &vb, NULL);
3215     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216     if(!vb) {
3217         skip("Failed to create a vertex buffer\n");
3218         return;
3219     }
3220     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222     if(!ib) {
3223         skip("Failed to create an index buffer\n");
3224         return;
3225     }
3226
3227     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229     memcpy(data, quad, sizeof(quad));
3230     hr = IDirect3DVertexBuffer9_Unlock(vb);
3231     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3232
3233     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235     memcpy(data, indices, sizeof(indices));
3236     hr = IDirect3DIndexBuffer9_Unlock(ib);
3237     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3238
3239     hr = IDirect3DDevice9_SetIndices(device, ib);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3245
3246     /* Now destroy the bound index buffer and draw again */
3247     ref = IDirect3DIndexBuffer9_Release(ib);
3248     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3249
3250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3252
3253     hr = IDirect3DDevice9_BeginScene(device);
3254     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255     if(SUCCEEDED(hr))
3256     {
3257         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258          * making assumptions about the indices or vertices
3259          */
3260         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262         hr = IDirect3DDevice9_EndScene(device);
3263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3264     }
3265
3266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3268
3269     hr = IDirect3DDevice9_SetIndices(device, NULL);
3270     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3273
3274     /* Index buffer was already destroyed as part of the test */
3275     IDirect3DVertexBuffer9_Release(vb);
3276 }
3277
3278 static void float_texture_test(IDirect3DDevice9 *device)
3279 {
3280     IDirect3D9 *d3d = NULL;
3281     HRESULT hr;
3282     IDirect3DTexture9 *texture = NULL;
3283     D3DLOCKED_RECT lr;
3284     float *data;
3285     DWORD color;
3286     float quad[] = {
3287         -1.0,      -1.0,       0.1,     0.0,    0.0,
3288         -1.0,       1.0,       0.1,     0.0,    1.0,
3289          1.0,      -1.0,       0.1,     1.0,    0.0,
3290          1.0,       1.0,       0.1,     1.0,    1.0,
3291     };
3292
3293     memset(&lr, 0, sizeof(lr));
3294     IDirect3DDevice9_GetDirect3D(device, &d3d);
3295     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297         skip("D3DFMT_R32F textures not supported\n");
3298         goto out;
3299     }
3300
3301     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302                                         D3DPOOL_MANAGED, &texture, NULL);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304     if(!texture) {
3305         skip("Failed to create R32F texture\n");
3306         goto out;
3307     }
3308
3309     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311     data = lr.pBits;
3312     *data = 0.0;
3313     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3315
3316     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3318
3319     hr = IDirect3DDevice9_BeginScene(device);
3320     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321     if(SUCCEEDED(hr))
3322     {
3323         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3325
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         hr = IDirect3DDevice9_EndScene(device);
3330         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3331     }
3332     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3334
3335     color = getPixelColor(device, 240, 320);
3336     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3337
3338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3340
3341 out:
3342     if(texture) IDirect3DTexture9_Release(texture);
3343     IDirect3D9_Release(d3d);
3344 }
3345
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3347 {
3348     IDirect3D9 *d3d = NULL;
3349     HRESULT hr;
3350     IDirect3DTexture9 *texture = NULL;
3351     D3DLOCKED_RECT lr;
3352     DWORD *data;
3353     DWORD color;
3354     float quad[] = {
3355        -1.0,      -1.0,       0.1,     0.0,    0.0,
3356        -1.0,       1.0,       0.1,     0.0,    1.0,
3357         1.0,      -1.0,       0.1,     1.0,    0.0,
3358         1.0,       1.0,       0.1,     1.0,    1.0,
3359     };
3360
3361     memset(&lr, 0, sizeof(lr));
3362     IDirect3DDevice9_GetDirect3D(device, &d3d);
3363     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365            skip("D3DFMT_G16R16 textures not supported\n");
3366            goto out;
3367     }
3368
3369     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370                                         D3DPOOL_MANAGED, &texture, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372     if(!texture) {
3373         skip("Failed to create D3DFMT_G16R16 texture\n");
3374         goto out;
3375     }
3376
3377     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379     data = lr.pBits;
3380     *data = 0x0f00f000;
3381     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3386
3387     hr = IDirect3DDevice9_BeginScene(device);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389     if(SUCCEEDED(hr))
3390     {
3391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3393
3394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396
3397         hr = IDirect3DDevice9_EndScene(device);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3399     }
3400     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3402
3403     color = getPixelColor(device, 240, 320);
3404     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3406
3407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409
3410 out:
3411     if(texture) IDirect3DTexture9_Release(texture);
3412     IDirect3D9_Release(d3d);
3413 }
3414
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3416 {
3417     HRESULT hr;
3418     IDirect3D9 *d3d;
3419     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420     D3DCAPS9 caps;
3421     IDirect3DTexture9 *texture = NULL;
3422     IDirect3DVolumeTexture9 *volume = NULL;
3423     unsigned int x, y, z;
3424     D3DLOCKED_RECT lr;
3425     D3DLOCKED_BOX lb;
3426     DWORD color;
3427     UINT w, h;
3428     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430                            0.0, 1.0, 0.0, 0.0,
3431                            0.0, 0.0, 1.0, 0.0,
3432                            0.0, 0.0, 0.0, 1.0};
3433     static const D3DVERTEXELEMENT9 decl_elements[] = {
3434         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436         D3DDECL_END()
3437     };
3438     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441         D3DDECL_END()
3442     };
3443     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446         D3DDECL_END()
3447     };
3448     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449                                                  0x00, 0xff, 0x00, 0x00,
3450                                                  0x00, 0x00, 0x00, 0x00,
3451                                                  0x00, 0x00, 0x00, 0x00};
3452
3453     memset(&lr, 0, sizeof(lr));
3454     memset(&lb, 0, sizeof(lb));
3455     IDirect3DDevice9_GetDirect3D(device, &d3d);
3456     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458         fmt = D3DFMT_A16B16G16R16;
3459     }
3460     IDirect3D9_Release(d3d);
3461
3462     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3486
3487     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489     w = min(1024, caps.MaxTextureWidth);
3490     h = min(1024, caps.MaxTextureHeight);
3491     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494     if(!texture) {
3495         skip("Failed to create the test texture\n");
3496         return;
3497     }
3498
3499     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501      * 1.0 in red and green for the x and y coords
3502      */
3503     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505     for(y = 0; y < h; y++) {
3506         for(x = 0; x < w; x++) {
3507             double r_f = (double) y / (double) h;
3508             double g_f = (double) x / (double) w;
3509             if(fmt == D3DFMT_A16B16G16R16) {
3510                 unsigned short r, g;
3511                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512                 r = (unsigned short) (r_f * 65536.0);
3513                 g = (unsigned short) (g_f * 65536.0);
3514                 dst[0] = r;
3515                 dst[1] = g;
3516                 dst[2] = 0;
3517                 dst[3] = 65535;
3518             } else {
3519                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520                 unsigned char r = (unsigned char) (r_f * 255.0);
3521                 unsigned char g = (unsigned char) (g_f * 255.0);
3522                 dst[0] = 0;
3523                 dst[1] = g;
3524                 dst[2] = r;
3525                 dst[3] = 255;
3526             }
3527         }
3528     }
3529     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3533
3534     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536     hr = IDirect3DDevice9_BeginScene(device);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538     if(SUCCEEDED(hr))
3539     {
3540         float quad1[] = {
3541             -1.0,      -1.0,       0.1,     1.0,    1.0,
3542             -1.0,       0.0,       0.1,     1.0,    1.0,
3543              0.0,      -1.0,       0.1,     1.0,    1.0,
3544              0.0,       0.0,       0.1,     1.0,    1.0,
3545         };
3546         float quad2[] = {
3547             -1.0,       0.0,       0.1,     1.0,    1.0,
3548             -1.0,       1.0,       0.1,     1.0,    1.0,
3549              0.0,       0.0,       0.1,     1.0,    1.0,
3550              0.0,       1.0,       0.1,     1.0,    1.0,
3551         };
3552         float quad3[] = {
3553              0.0,       0.0,       0.1,     0.5,    0.5,
3554              0.0,       1.0,       0.1,     0.5,    0.5,
3555              1.0,       0.0,       0.1,     0.5,    0.5,
3556              1.0,       1.0,       0.1,     0.5,    0.5,
3557         };
3558         float quad4[] = {
3559              320,       480,       0.1,     1.0,    0.0,    1.0,
3560              320,       240,       0.1,     1.0,    0.0,    1.0,
3561              640,       480,       0.1,     1.0,    0.0,    1.0,
3562              640,       240,       0.1,     1.0,    0.0,    1.0,
3563         };
3564         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565                           0.0, 0.0, 0.0, 0.0,
3566                           0.0, 0.0, 0.0, 0.0,
3567                           0.0, 0.0, 0.0, 0.0};
3568
3569         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3574
3575         /* What happens with transforms enabled? */
3576         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3580
3581         /* What happens if 4 coords are used, but only 2 given ?*/
3582         mat[8] = 1.0;
3583         mat[13] = 1.0;
3584         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3590
3591         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593          * due to the coords in the vertices. (turns out red, indeed)
3594          */
3595         memset(mat, 0, sizeof(mat));
3596         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3604
3605         hr = IDirect3DDevice9_EndScene(device);
3606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3607     }
3608     color = getPixelColor(device, 160, 360);
3609     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610     color = getPixelColor(device, 160, 120);
3611     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612     color = getPixelColor(device, 480, 120);
3613     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614     color = getPixelColor(device, 480, 360);
3615     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3618
3619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3621
3622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624     hr = IDirect3DDevice9_BeginScene(device);
3625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626     if(SUCCEEDED(hr))
3627     {
3628         float quad1[] = {
3629             -1.0,      -1.0,       0.1,     0.8,    0.2,
3630             -1.0,       0.0,       0.1,     0.8,    0.2,
3631              0.0,      -1.0,       0.1,     0.8,    0.2,
3632              0.0,       0.0,       0.1,     0.8,    0.2,
3633         };
3634         float quad2[] = {
3635             -1.0,       0.0,       0.1,     0.5,    1.0,
3636             -1.0,       1.0,       0.1,     0.5,    1.0,
3637              0.0,       0.0,       0.1,     0.5,    1.0,
3638              0.0,       1.0,       0.1,     0.5,    1.0,
3639         };
3640         float quad3[] = {
3641              0.0,       0.0,       0.1,     0.5,    1.0,
3642              0.0,       1.0,       0.1,     0.5,    1.0,
3643              1.0,       0.0,       0.1,     0.5,    1.0,
3644              1.0,       1.0,       0.1,     0.5,    1.0,
3645         };
3646         float quad4[] = {
3647              0.0,      -1.0,       0.1,     0.8,    0.2,
3648              0.0,       0.0,       0.1,     0.8,    0.2,
3649              1.0,      -1.0,       0.1,     0.8,    0.2,
3650              1.0,       0.0,       0.1,     0.8,    0.2,
3651         };
3652         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653                           0.0, 0.0, 0.0, 0.0,
3654                           0.0, 1.0, 0.0, 0.0,
3655                           0.0, 0.0, 0.0, 0.0};
3656
3657         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3658          */
3659         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3663
3664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3666
3667         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668          * it behaves like COUNT2 because normal textures require 2 coords
3669          */
3670         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3674
3675         /* Just to be sure, the same as quad2 above */
3676         memset(mat, 0, sizeof(mat));
3677         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685          * used? And what happens to the first?
3686          */
3687         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3691
3692         hr = IDirect3DDevice9_EndScene(device);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3694     }
3695     color = getPixelColor(device, 160, 360);
3696     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697     color = getPixelColor(device, 160, 120);
3698     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699     color = getPixelColor(device, 480, 120);
3700     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702     color = getPixelColor(device, 480, 360);
3703     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3707
3708     IDirect3DTexture9_Release(texture);
3709
3710     /* Test projected textures, without any fancy matrices */
3711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3719
3720     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722     for(x = 0; x < 4; x++) {
3723         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3724     }
3725     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3729
3730     hr = IDirect3DDevice9_BeginScene(device);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732     if(SUCCEEDED(hr))
3733     {
3734         const float proj_quads[] = {
3735            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3736             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3737            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3738             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3739            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3740             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3741            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3742             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3743         };
3744
3745         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3749
3750         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3754
3755         hr = IDirect3DDevice9_EndScene(device);
3756         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3757     }
3758
3759     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761     IDirect3DTexture9_Release(texture);
3762
3763     color = getPixelColor(device, 158, 118);
3764     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765     color = getPixelColor(device, 162, 118);
3766     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767     color = getPixelColor(device, 158, 122);
3768     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769     color = getPixelColor(device, 162, 122);
3770     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3771
3772     color = getPixelColor(device, 158, 178);
3773     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774     color = getPixelColor(device, 162, 178);
3775     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776     color = getPixelColor(device, 158, 182);
3777     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778     color = getPixelColor(device, 162, 182);
3779     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3780
3781     color = getPixelColor(device, 318, 118);
3782     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783     color = getPixelColor(device, 322, 118);
3784     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785     color = getPixelColor(device, 318, 122);
3786     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787     color = getPixelColor(device, 322, 122);
3788     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3789
3790     color = getPixelColor(device, 318, 178);
3791     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792     color = getPixelColor(device, 322, 178);
3793     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794     color = getPixelColor(device, 318, 182);
3795     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796     color = getPixelColor(device, 322, 182);
3797     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3798
3799     color = getPixelColor(device, 238, 298);
3800     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801     color = getPixelColor(device, 242, 298);
3802     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 238, 302);
3804     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 242, 302);
3806     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3807
3808     color = getPixelColor(device, 238, 388);
3809     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810     color = getPixelColor(device, 242, 388);
3811     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812     color = getPixelColor(device, 238, 392);
3813     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 242, 392);
3815     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3816
3817     color = getPixelColor(device, 478, 298);
3818     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819     color = getPixelColor(device, 482, 298);
3820     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 478, 302);
3822     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823     color = getPixelColor(device, 482, 302);
3824     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3825
3826     color = getPixelColor(device, 478, 388);
3827     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828     color = getPixelColor(device, 482, 388);
3829     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830     color = getPixelColor(device, 478, 392);
3831     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 482, 392);
3833     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3834
3835     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3837
3838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841      * Thus watch out if sampling from texels between 0 and 1.
3842      */
3843     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846     if(!volume) {
3847         skip("Failed to create a volume texture\n");
3848         goto out;
3849     }
3850
3851     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853     for(z = 0; z < 32; z++) {
3854         for(y = 0; y < 32; y++) {
3855             for(x = 0; x < 32; x++) {
3856                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858                 float r_f = (float) x / 31.0;
3859                 float g_f = (float) y / 31.0;
3860                 float b_f = (float) z / 31.0;
3861
3862                 if(fmt == D3DFMT_A16B16G16R16) {
3863                     unsigned short *mem_s = mem;
3864                     mem_s[0]  = r_f * 65535.0;
3865                     mem_s[1]  = g_f * 65535.0;
3866                     mem_s[2]  = b_f * 65535.0;
3867                     mem_s[3]  = 65535;
3868                 } else {
3869                     unsigned char *mem_c = mem;
3870                     mem_c[0]  = b_f * 255.0;
3871                     mem_c[1]  = g_f * 255.0;
3872                     mem_c[2]  = r_f * 255.0;
3873                     mem_c[3]  = 255;
3874                 }
3875             }
3876         }
3877     }
3878     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3880
3881     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3883
3884     hr = IDirect3DDevice9_BeginScene(device);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886     if(SUCCEEDED(hr))
3887     {
3888         float quad1[] = {
3889             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3890             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3891              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3892              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3893         };
3894         float quad2[] = {
3895             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3896             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3897              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3898              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3899         };
3900         float quad3[] = {
3901              0.0,       0.0,       0.1,     0.0,    0.0,
3902              0.0,       1.0,       0.1,     0.0,    0.0,
3903              1.0,       0.0,       0.1,     0.0,    0.0,
3904              1.0,       1.0,       0.1,     0.0,    0.0
3905         };
3906         float quad4[] = {
3907              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3908              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3909              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3910              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3911         };
3912         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913                          0.0, 0.0, 1.0, 0.0,
3914                          0.0, 1.0, 0.0, 0.0,
3915                          0.0, 0.0, 0.0, 1.0};
3916         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3918
3919         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920          * values
3921          */
3922         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3928
3929         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931          * otherwise the w will be missing(blue).
3932          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3934          */
3935         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3939
3940         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3941         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3949
3950         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951          * disable. ATI extends it up to the amount of values needed for the volume texture
3952          */
3953         memset(mat, 0, sizeof(mat));
3954         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3962
3963         hr = IDirect3DDevice9_EndScene(device);
3964         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3965     }
3966
3967     color = getPixelColor(device, 160, 360);
3968     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969     color = getPixelColor(device, 160, 120);
3970     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972     color = getPixelColor(device, 480, 120);
3973     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974     color = getPixelColor(device, 480, 360);
3975     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3976
3977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3979
3980     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982     hr = IDirect3DDevice9_BeginScene(device);
3983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984     if(SUCCEEDED(hr))
3985     {
3986         float quad1[] = {
3987             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3988             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3989              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3990              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3991         };
3992         float quad2[] = {
3993             -1.0,       0.0,       0.1,
3994             -1.0,       1.0,       0.1,
3995              0.0,       0.0,       0.1,
3996              0.0,       1.0,       0.1,
3997         };
3998         float quad3[] = {
3999              0.0,       0.0,       0.1,     1.0,
4000              0.0,       1.0,       0.1,     1.0,
4001              1.0,       0.0,       0.1,     1.0,
4002              1.0,       1.0,       0.1,     1.0
4003         };
4004         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4005                            0.0, 0.0, 0.0, 0.0,
4006                            0.0, 0.0, 0.0, 0.0,
4007                            0.0, 1.0, 0.0, 0.0};
4008         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009                            1.0, 0.0, 0.0, 0.0,
4010                            0.0, 1.0, 0.0, 0.0,
4011                            0.0, 0.0, 1.0, 0.0};
4012         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014
4015         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4016          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4017          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4018          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4019          * 4th *input* coordinate.
4020          */
4021         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4022         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4023         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4024         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4025         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4026         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4027
4028         /* None passed */
4029         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4030         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4031         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4032         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4033         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4034         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4035
4036         /* 4 used, 1 passed */
4037         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4038         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4039         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4040         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4041         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4042         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4043
4044         hr = IDirect3DDevice9_EndScene(device);
4045         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4046     }
4047     color = getPixelColor(device, 160, 360);
4048     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4049     color = getPixelColor(device, 160, 120);
4050     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4051     color = getPixelColor(device, 480, 120);
4052     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4053     /* Quad4: unused */
4054
4055     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4056     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4057
4058     IDirect3DVolumeTexture9_Release(volume);
4059
4060     out:
4061     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4063     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4064     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4065     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4066     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4067     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4068     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4069     IDirect3DVertexDeclaration9_Release(decl);
4070     IDirect3DVertexDeclaration9_Release(decl2);
4071     IDirect3DVertexDeclaration9_Release(decl3);
4072 }
4073
4074 static void texdepth_test(IDirect3DDevice9 *device)
4075 {
4076     IDirect3DPixelShader9 *shader;
4077     HRESULT hr;
4078     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4079     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4080     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4081     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4082     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4083     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4084     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4085     DWORD shader_code[] = {
4086         0xffff0104,                                                                 /* ps_1_4               */
4087         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4088         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4089         0x0000fffd,                                                                 /* phase                */
4090         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4091         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4092         0x0000ffff                                                                  /* end                  */
4093     };
4094     DWORD color;
4095     float vertex[] = {
4096        -1.0,   -1.0,    0.0,
4097         1.0,   -1.0,    1.0,
4098        -1.0,    1.0,    0.0,
4099         1.0,    1.0,    1.0
4100     };
4101
4102     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4103     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4104
4105     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4110     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4113     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4114     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4115
4116     /* Fill the depth buffer with a gradient */
4117     hr = IDirect3DDevice9_BeginScene(device);
4118     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4119     if(SUCCEEDED(hr))
4120     {
4121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4122         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4123         hr = IDirect3DDevice9_EndScene(device);
4124         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4125     }
4126
4127     /* Now perform the actual tests. Same geometry, but with the shader */
4128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4132     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4133     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4134
4135     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4136     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4137     hr = IDirect3DDevice9_BeginScene(device);
4138     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4139     if(SUCCEEDED(hr))
4140     {
4141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4142         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4143
4144         hr = IDirect3DDevice9_EndScene(device);
4145         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4146     }
4147
4148     color = getPixelColor(device, 158, 240);
4149     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4150     color = getPixelColor(device, 162, 240);
4151     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4152
4153     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4155
4156     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4157     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4158
4159     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4160     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4161     hr = IDirect3DDevice9_BeginScene(device);
4162     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4163     if(SUCCEEDED(hr))
4164     {
4165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4166         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4167
4168         hr = IDirect3DDevice9_EndScene(device);
4169         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4170     }
4171
4172     color = getPixelColor(device, 318, 240);
4173     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4174     color = getPixelColor(device, 322, 240);
4175     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4176
4177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4178     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4179
4180     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4181     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4182
4183     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4184     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4185     hr = IDirect3DDevice9_BeginScene(device);
4186     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4187     if(SUCCEEDED(hr))
4188     {
4189         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4190         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4191
4192         hr = IDirect3DDevice9_EndScene(device);
4193         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4194     }
4195
4196     color = getPixelColor(device, 1, 240);
4197     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4198
4199     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4200     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4201
4202     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4203     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4204
4205     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4206     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4207     hr = IDirect3DDevice9_BeginScene(device);
4208     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4209     if(SUCCEEDED(hr))
4210     {
4211         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4212         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4213
4214         hr = IDirect3DDevice9_EndScene(device);
4215         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4216     }
4217     color = getPixelColor(device, 318, 240);
4218     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4219     color = getPixelColor(device, 322, 240);
4220     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4221
4222     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4223     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4224
4225     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4226     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4227
4228     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4229     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4230     hr = IDirect3DDevice9_BeginScene(device);
4231     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4232     if(SUCCEEDED(hr))
4233     {
4234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4235         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4236
4237         hr = IDirect3DDevice9_EndScene(device);
4238         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4239     }
4240
4241     color = getPixelColor(device, 1, 240);
4242     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4243
4244     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4245     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4246
4247     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4248     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4249
4250     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4252     hr = IDirect3DDevice9_BeginScene(device);
4253     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4254     if(SUCCEEDED(hr))
4255     {
4256         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4257         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4258
4259         hr = IDirect3DDevice9_EndScene(device);
4260         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4261     }
4262
4263     color = getPixelColor(device, 638, 240);
4264     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4265
4266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4268
4269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4270     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4271
4272     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4273     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4274     hr = IDirect3DDevice9_BeginScene(device);
4275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4276     if(SUCCEEDED(hr))
4277     {
4278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4279         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4280
4281         hr = IDirect3DDevice9_EndScene(device);
4282         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4283     }
4284
4285     color = getPixelColor(device, 638, 240);
4286     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4287
4288     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4290
4291     /* Cleanup */
4292     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4293     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4294     IDirect3DPixelShader9_Release(shader);
4295
4296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4300 }
4301
4302 static void texkill_test(IDirect3DDevice9 *device)
4303 {
4304     IDirect3DPixelShader9 *shader;
4305     HRESULT hr;
4306     DWORD color;
4307
4308     const float vertex[] = {
4309     /*                          bottom  top    right    left */
4310         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4311          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4312         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4313          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4314     };
4315
4316     DWORD shader_code_11[] = {
4317     0xffff0101,                                                             /* ps_1_1                     */
4318     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4319     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4320     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4321     0x0000ffff                                                              /* end                        */
4322     };
4323     DWORD shader_code_20[] = {
4324     0xffff0200,                                                             /* ps_2_0                     */
4325     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4326     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4327     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4328     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4329     0x0000ffff                                                              /* end                        */
4330     };
4331
4332     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4333     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4334     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4335     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4336
4337     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4338     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4339     hr = IDirect3DDevice9_BeginScene(device);
4340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4341     if(SUCCEEDED(hr))
4342     {
4343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4346         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4347         hr = IDirect3DDevice9_EndScene(device);
4348         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4349     }
4350     color = getPixelColor(device, 63, 46);
4351     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4352     color = getPixelColor(device, 66, 46);
4353     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4354     color = getPixelColor(device, 63, 49);
4355     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4356     color = getPixelColor(device, 66, 49);
4357     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4358
4359     color = getPixelColor(device, 578, 46);
4360     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4361     color = getPixelColor(device, 575, 46);
4362     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4363     color = getPixelColor(device, 578, 49);
4364     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4365     color = getPixelColor(device, 575, 49);
4366     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4367
4368     color = getPixelColor(device, 63, 430);
4369     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4370     color = getPixelColor(device, 63, 433);
4371     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4372     color = getPixelColor(device, 66, 433);
4373     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4374     color = getPixelColor(device, 66, 430);
4375     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4376
4377     color = getPixelColor(device, 578, 430);
4378     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4379     color = getPixelColor(device, 578, 433);
4380     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4381     color = getPixelColor(device, 575, 433);
4382     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4383     color = getPixelColor(device, 575, 430);
4384     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4385
4386     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4387     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4388
4389     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4390     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4391     IDirect3DPixelShader9_Release(shader);
4392
4393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4395     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4396     if(FAILED(hr)) {
4397         skip("Failed to create 2.0 test shader, most likely not supported\n");
4398         return;
4399     }
4400
4401     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4402     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4403     hr = IDirect3DDevice9_BeginScene(device);
4404     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4405     if(SUCCEEDED(hr))
4406     {
4407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4409         hr = IDirect3DDevice9_EndScene(device);
4410         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4411     }
4412
4413     color = getPixelColor(device, 63, 46);
4414     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4415     color = getPixelColor(device, 66, 46);
4416     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4417     color = getPixelColor(device, 63, 49);
4418     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4419     color = getPixelColor(device, 66, 49);
4420     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4421
4422     color = getPixelColor(device, 578, 46);
4423     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4424     color = getPixelColor(device, 575, 46);
4425     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4426     color = getPixelColor(device, 578, 49);
4427     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4428     color = getPixelColor(device, 575, 49);
4429     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4430
4431     color = getPixelColor(device, 63, 430);
4432     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4433     color = getPixelColor(device, 63, 433);
4434     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4435     color = getPixelColor(device, 66, 433);
4436     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4437     color = getPixelColor(device, 66, 430);
4438     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4439
4440     color = getPixelColor(device, 578, 430);
4441     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4442     color = getPixelColor(device, 578, 433);
4443     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4444     color = getPixelColor(device, 575, 433);
4445     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4446     color = getPixelColor(device, 575, 430);
4447     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4448
4449     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4450     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4451
4452     /* Cleanup */
4453     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4454     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4455     IDirect3DPixelShader9_Release(shader);
4456 }
4457
4458 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4459 {
4460     IDirect3D9 *d3d9;
4461     HRESULT hr;
4462     IDirect3DTexture9 *texture;
4463     IDirect3DPixelShader9 *shader;
4464     IDirect3DPixelShader9 *shader2;
4465     D3DLOCKED_RECT lr;
4466     DWORD color;
4467     DWORD shader_code[] = {
4468         0xffff0101,                             /* ps_1_1       */
4469         0x00000042, 0xb00f0000,                 /* tex t0       */
4470         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4471         0x0000ffff                              /* end          */
4472     };
4473     DWORD shader_code2[] = {
4474         0xffff0101,                             /* ps_1_1       */
4475         0x00000042, 0xb00f0000,                 /* tex t0       */
4476         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4477         0x0000ffff                              /* end          */
4478     };
4479
4480     float quad[] = {
4481        -1.0,   -1.0,   0.1,     0.5,    0.5,
4482         1.0,   -1.0,   0.1,     0.5,    0.5,
4483        -1.0,    1.0,   0.1,     0.5,    0.5,
4484         1.0,    1.0,   0.1,     0.5,    0.5,
4485     };
4486
4487     memset(&lr, 0, sizeof(lr));
4488     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4489     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4490                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4491     IDirect3D9_Release(d3d9);
4492     if(FAILED(hr)) {
4493         skip("No D3DFMT_X8L8V8U8 support\n");
4494         return;
4495     };
4496
4497     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4498     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4499
4500     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4501     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4502     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4503     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4504     *((DWORD *) lr.pBits) = 0x11ca3141;
4505     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4506     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4507
4508     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4510     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4511     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4512
4513     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4515     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4517     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4518     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4519
4520     hr = IDirect3DDevice9_BeginScene(device);
4521     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4522     if(SUCCEEDED(hr))
4523     {
4524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4525         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4526
4527         hr = IDirect3DDevice9_EndScene(device);
4528         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4529     }
4530     color = getPixelColor(device, 578, 430);
4531     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4532        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4533     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4535
4536     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4537     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4538     hr = IDirect3DDevice9_BeginScene(device);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4540     if(SUCCEEDED(hr))
4541     {
4542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4543         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4544
4545         hr = IDirect3DDevice9_EndScene(device);
4546         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4547     }
4548     color = getPixelColor(device, 578, 430);
4549     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4550     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4551     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4552
4553     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4554     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4557     IDirect3DPixelShader9_Release(shader);
4558     IDirect3DPixelShader9_Release(shader2);
4559     IDirect3DTexture9_Release(texture);
4560 }
4561
4562 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4563 {
4564     HRESULT hr;
4565     IDirect3D9 *d3d;
4566     IDirect3DTexture9 *texture = NULL;
4567     IDirect3DSurface9 *surface;
4568     DWORD color;
4569     const RECT r1 = {256, 256, 512, 512};
4570     const RECT r2 = {512, 256, 768, 512};
4571     const RECT r3 = {256, 512, 512, 768};
4572     const RECT r4 = {512, 512, 768, 768};
4573     unsigned int x, y;
4574     D3DLOCKED_RECT lr;
4575     memset(&lr, 0, sizeof(lr));
4576
4577     IDirect3DDevice9_GetDirect3D(device, &d3d);
4578     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4579        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4580         skip("No autogenmipmap support\n");
4581         IDirect3D9_Release(d3d);
4582         return;
4583     }
4584     IDirect3D9_Release(d3d);
4585
4586     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4587     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4588
4589     /* Make the mipmap big, so that a smaller mipmap is used
4590      */
4591     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4592                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4593     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4594
4595     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4596     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4597     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4598     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4599     for(y = 0; y < 1024; y++) {
4600         for(x = 0; x < 1024; x++) {
4601             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4602             POINT pt;
4603
4604             pt.x = x;
4605             pt.y = y;
4606             if(PtInRect(&r1, pt)) {
4607                 *dst = 0xffff0000;
4608             } else if(PtInRect(&r2, pt)) {
4609                 *dst = 0xff00ff00;
4610             } else if(PtInRect(&r3, pt)) {
4611                 *dst = 0xff0000ff;
4612             } else if(PtInRect(&r4, pt)) {
4613                 *dst = 0xff000000;
4614             } else {
4615                 *dst = 0xffffffff;
4616             }
4617         }
4618     }
4619     hr = IDirect3DSurface9_UnlockRect(surface);
4620     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4621     IDirect3DSurface9_Release(surface);
4622
4623     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4625     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4626     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4627
4628     hr = IDirect3DDevice9_BeginScene(device);
4629     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4630     if(SUCCEEDED(hr)) {
4631         const float quad[] =  {
4632            -0.5,   -0.5,    0.1,    0.0,    0.0,
4633            -0.5,    0.5,    0.1,    0.0,    1.0,
4634             0.5,   -0.5,    0.1,    1.0,    0.0,
4635             0.5,    0.5,    0.1,    1.0,    1.0
4636         };
4637
4638         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4639         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4641         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4642         hr = IDirect3DDevice9_EndScene(device);
4643         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4644     }
4645     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4646     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4647     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4649     IDirect3DTexture9_Release(texture);
4650
4651     color = getPixelColor(device, 200, 200);
4652     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4653     color = getPixelColor(device, 280, 200);
4654     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4655     color = getPixelColor(device, 360, 200);
4656     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4657     color = getPixelColor(device, 440, 200);
4658     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4659     color = getPixelColor(device, 200, 270);
4660     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4661     color = getPixelColor(device, 280, 270);
4662     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4663     color = getPixelColor(device, 360, 270);
4664     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4665     color = getPixelColor(device, 440, 270);
4666     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4667     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4668     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4669 }
4670
4671 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4672 {
4673     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4674     IDirect3DVertexDeclaration9 *decl;
4675     HRESULT hr;
4676     DWORD color;
4677     DWORD shader_code_11[] =  {
4678         0xfffe0101,                                         /* vs_1_1           */
4679         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4680         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4681         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4682         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4683         0x0000ffff                                          /* end              */
4684     };
4685     DWORD shader_code_11_2[] =  {
4686         0xfffe0101,                                         /* vs_1_1           */
4687         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4688         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4689         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4690         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4691         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4692         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4693         0x0000ffff                                          /* end              */
4694     };
4695     DWORD shader_code_20[] =  {
4696         0xfffe0200,                                         /* vs_2_0           */
4697         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4698         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4699         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4700         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4701         0x0000ffff                                          /* end              */
4702     };
4703     DWORD shader_code_20_2[] =  {
4704         0xfffe0200,                                         /* vs_2_0           */
4705         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4706         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4707         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4708         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4709         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4710         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4711         0x0000ffff                                          /* end              */
4712     };
4713     static const D3DVERTEXELEMENT9 decl_elements[] = {
4714         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4715         D3DDECL_END()
4716     };
4717     float quad1[] = {
4718         -1.0,   -1.0,   0.1,
4719          0.0,   -1.0,   0.1,
4720         -1.0,    0.0,   0.1,
4721          0.0,    0.0,   0.1
4722     };
4723     float quad2[] = {
4724          0.0,   -1.0,   0.1,
4725          1.0,   -1.0,   0.1,
4726          0.0,    0.0,   0.1,
4727          1.0,    0.0,   0.1
4728     };
4729     float quad3[] = {
4730          0.0,    0.0,   0.1,
4731          1.0,    0.0,   0.1,
4732          0.0,    1.0,   0.1,
4733          1.0,    1.0,   0.1
4734     };
4735     float quad4[] = {
4736         -1.0,    0.0,   0.1,
4737          0.0,    0.0,   0.1,
4738         -1.0,    1.0,   0.1,
4739          0.0,    1.0,   0.1
4740     };
4741     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4742     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4743
4744     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4749     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4750     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4751     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4752     if(FAILED(hr)) shader_20 = NULL;
4753     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4754     if(FAILED(hr)) shader_20_2 = NULL;
4755     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4756     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4757
4758     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4760     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4762     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4763     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4764
4765     hr = IDirect3DDevice9_BeginScene(device);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4767     if(SUCCEEDED(hr))
4768     {
4769         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4770         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4772         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4773
4774         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4775         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4777         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4778
4779         if(shader_20) {
4780             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4781             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4782             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4783             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4784         }
4785
4786         if(shader_20_2) {
4787             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4788             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4789             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4790             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791         }
4792
4793         hr = IDirect3DDevice9_EndScene(device);
4794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4795     }
4796
4797     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4798     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4799     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4800     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4801
4802     color = getPixelColor(device, 160, 360);
4803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4804        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4805     color = getPixelColor(device, 480, 360);
4806     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4808     if(shader_20) {
4809         color = getPixelColor(device, 480, 120);
4810         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4811            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4812     }
4813     if(shader_20_2) {
4814         color = getPixelColor(device, 160, 120);
4815         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4816            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4817     }
4818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4819     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4820
4821     IDirect3DVertexDeclaration9_Release(decl);
4822     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4823     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4824     IDirect3DVertexShader9_Release(shader_11_2);
4825     IDirect3DVertexShader9_Release(shader_11);
4826 }
4827
4828 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4829 {
4830     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4831     HRESULT hr;
4832     DWORD color;
4833     DWORD shader_code_11[] =  {
4834         0xffff0101,                                         /* ps_1_1           */
4835         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4836         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4837         0x0000ffff                                          /* end              */
4838     };
4839     DWORD shader_code_12[] =  {
4840         0xffff0102,                                         /* ps_1_2           */
4841         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4842         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4843         0x0000ffff                                          /* end              */
4844     };
4845     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4846      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4847      * During development of this test, 1.3 shaders were verified too
4848      */
4849     DWORD shader_code_14[] =  {
4850         0xffff0104,                                         /* ps_1_4           */
4851         /* Try to make one constant local. It gets clamped too, although the binary contains
4852          * the bigger numbers
4853          */
4854         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4855         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4856         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4857         0x0000ffff                                          /* end              */
4858     };
4859     DWORD shader_code_20[] =  {
4860         0xffff0200,                                         /* ps_2_0           */
4861         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4862         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4863         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4864         0x0000ffff                                          /* end              */
4865     };
4866     float quad1[] = {
4867         -1.0,   -1.0,   0.1,
4868          0.0,   -1.0,   0.1,
4869         -1.0,    0.0,   0.1,
4870          0.0,    0.0,   0.1
4871     };
4872     float quad2[] = {
4873          0.0,   -1.0,   0.1,
4874          1.0,   -1.0,   0.1,
4875          0.0,    0.0,   0.1,
4876          1.0,    0.0,   0.1
4877     };
4878     float quad3[] = {
4879          0.0,    0.0,   0.1,
4880          1.0,    0.0,   0.1,
4881          0.0,    1.0,   0.1,
4882          1.0,    1.0,   0.1
4883     };
4884     float quad4[] = {
4885         -1.0,    0.0,   0.1,
4886          0.0,    0.0,   0.1,
4887         -1.0,    1.0,   0.1,
4888          0.0,    1.0,   0.1
4889     };
4890     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4891     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4892
4893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4895
4896     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4899     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4900     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4901     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4902     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4903     if(FAILED(hr)) shader_20 = NULL;
4904
4905     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4906     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4907     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4908     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4910     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4911
4912     hr = IDirect3DDevice9_BeginScene(device);
4913     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4914     if(SUCCEEDED(hr))
4915     {
4916         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4917         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4919         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4920
4921         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4922         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4924         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4925
4926         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4927         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4929         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4930
4931         if(shader_20) {
4932             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4933             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4934             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4935             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4936         }
4937
4938         hr = IDirect3DDevice9_EndScene(device);
4939         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4940     }
4941     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4942     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4943
4944     color = getPixelColor(device, 160, 360);
4945     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4946        "quad 1 has color %08x, expected 0x00808000\n", color);
4947     color = getPixelColor(device, 480, 360);
4948     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4949        "quad 2 has color %08x, expected 0x00808000\n", color);
4950     color = getPixelColor(device, 480, 120);
4951     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4952        "quad 3 has color %08x, expected 0x00808000\n", color);
4953     if(shader_20) {
4954         color = getPixelColor(device, 160, 120);
4955         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4956            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4957     }
4958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4960
4961     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4962     IDirect3DPixelShader9_Release(shader_14);
4963     IDirect3DPixelShader9_Release(shader_12);
4964     IDirect3DPixelShader9_Release(shader_11);
4965 }
4966
4967 static void dp2add_ps_test(IDirect3DDevice9 *device)
4968 {
4969     IDirect3DPixelShader9 *shader_dp2add = NULL;
4970     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4971     HRESULT hr;
4972     DWORD color;
4973
4974     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4975      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4976      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4977      * r0 first.
4978      * The result here for the r,g,b components should be roughly 0.5:
4979      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4980     static const DWORD shader_code_dp2add[] =  {
4981         0xffff0200,                                                             /* ps_2_0                       */
4982         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4983
4984         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4985         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4986
4987         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4988         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4989         0x0000ffff                                                              /* end                          */
4990     };
4991
4992     /* Test the _sat modifier, too.  Result here should be:
4993      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4994      *      _SAT: ==> 1.0
4995      *   ADD: (1.0 + -0.5) = 0.5
4996      */
4997     static const DWORD shader_code_dp2add_sat[] =  {
4998         0xffff0200,                                                             /* ps_2_0                           */
4999         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5000
5001         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5002         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5003         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5004
5005         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5006         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5007         0x0000ffff                                                              /* end                              */
5008     };
5009
5010     const float quad[] = {
5011         -1.0,   -1.0,   0.1,
5012          1.0,   -1.0,   0.1,
5013         -1.0,    1.0,   0.1,
5014          1.0,    1.0,   0.1
5015     };
5016
5017
5018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5020
5021     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5022     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5023
5024     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5025     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5026
5027     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5028     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5029
5030     if (shader_dp2add) {
5031
5032         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5033         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5034
5035         hr = IDirect3DDevice9_BeginScene(device);
5036         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5037         if(SUCCEEDED(hr))
5038         {
5039             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5040             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5041
5042             hr = IDirect3DDevice9_EndScene(device);
5043             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5044         }
5045
5046         color = getPixelColor(device, 360, 240);
5047         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5048                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5049
5050         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5051         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5052
5053         IDirect3DPixelShader9_Release(shader_dp2add);
5054     } else {
5055         skip("dp2add shader creation failed\n");
5056     }
5057
5058     if (shader_dp2add_sat) {
5059
5060         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5061         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5062
5063         hr = IDirect3DDevice9_BeginScene(device);
5064         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5065         if(SUCCEEDED(hr))
5066         {
5067             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5068             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5069
5070             hr = IDirect3DDevice9_EndScene(device);
5071             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5072         }
5073
5074         color = getPixelColor(device, 360, 240);
5075         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5076                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5077
5078         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5080
5081         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5082     } else {
5083         skip("dp2add shader creation failed\n");
5084     }
5085
5086     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5087     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5088 }
5089
5090 static void cnd_test(IDirect3DDevice9 *device)
5091 {
5092     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5093     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5094     HRESULT hr;
5095     DWORD color;
5096     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5097      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5098      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5099      */
5100     DWORD shader_code_11[] =  {
5101         0xffff0101,                                                                 /* ps_1_1               */
5102         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5103         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5104         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5105         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5106         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5107         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5108         0x0000ffff                                                                  /* end                  */
5109     };
5110     DWORD shader_code_12[] =  {
5111         0xffff0102,                                                                 /* ps_1_2               */
5112         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5113         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5114         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5115         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5116         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5117         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5118         0x0000ffff                                                                  /* end                  */
5119     };
5120     DWORD shader_code_13[] =  {
5121         0xffff0103,                                                                 /* ps_1_3               */
5122         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5123         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5124         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5125         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5126         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5127         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5128         0x0000ffff                                                                  /* end                  */
5129     };
5130     DWORD shader_code_14[] =  {
5131         0xffff0104,                                                                 /* ps_1_3               */
5132         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5133         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5134         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5135         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5136         0x0000ffff                                                                  /* end                  */
5137     };
5138
5139     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5140      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5141      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5142      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5143      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5144      * good enough.
5145      *
5146      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5147      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5148      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5149      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5150      */
5151     DWORD shader_code_11_coissue[] =  {
5152         0xffff0101,                                                             /* ps_1_1                   */
5153         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5154         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5155         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5156         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5157         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5158         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5159         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5160         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5161         /* 0x40000000 = D3DSI_COISSUE */
5162         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5163         0x0000ffff                                                              /* end                      */
5164     };
5165     DWORD shader_code_12_coissue[] =  {
5166         0xffff0102,                                                             /* ps_1_2                   */
5167         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5168         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5169         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5170         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5171         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5172         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5173         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5174         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5175         /* 0x40000000 = D3DSI_COISSUE */
5176         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5177         0x0000ffff                                                              /* end                      */
5178     };
5179     DWORD shader_code_13_coissue[] =  {
5180         0xffff0103,                                                             /* ps_1_3                   */
5181         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5182         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5183         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5184         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5185         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5186         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5187         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5188         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5189         /* 0x40000000 = D3DSI_COISSUE */
5190         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5191         0x0000ffff                                                              /* end                      */
5192     };
5193     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5194      * compare against 0.5
5195      */
5196     DWORD shader_code_14_coissue[] =  {
5197         0xffff0104,                                                             /* ps_1_4                   */
5198         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5199         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5200         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5201         /* 0x40000000 = D3DSI_COISSUE */
5202         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5203         0x0000ffff                                                              /* end                      */
5204     };
5205     float quad1[] = {
5206         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5207          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5208         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5209          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5210     };
5211     float quad2[] = {
5212          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5213          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5214          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5215          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5216     };
5217     float quad3[] = {
5218          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5219          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5220          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5221          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5222     };
5223     float quad4[] = {
5224         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5225          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5226         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5227          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5228     };
5229     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5230     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5231     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5232     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5233
5234     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5235     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5236
5237     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5238     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5239     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5240     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5241     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5242     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5243     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5244     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5245     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5246     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5247     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5248     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5249     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5250     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5251     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5252     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5253
5254     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5255     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5256     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5257     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5258     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5259     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5260
5261     hr = IDirect3DDevice9_BeginScene(device);
5262     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5263     if(SUCCEEDED(hr))
5264     {
5265         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5266         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5268         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5269
5270         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5271         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5274
5275         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5276         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5277         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5278         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5279
5280         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5281         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5283         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5284
5285         hr = IDirect3DDevice9_EndScene(device);
5286         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5287     }
5288
5289     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5291
5292     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5293     color = getPixelColor(device, 158, 118);
5294     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5295     color = getPixelColor(device, 162, 118);
5296     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5297     color = getPixelColor(device, 158, 122);
5298     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5299     color = getPixelColor(device, 162, 122);
5300     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5301
5302     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5303     color = getPixelColor(device, 158, 358);
5304     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5305     color = getPixelColor(device, 162, 358);
5306     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5307         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5308     color = getPixelColor(device, 158, 362);
5309     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5310     color = getPixelColor(device, 162, 362);
5311     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5312         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5313
5314     /* 1.2 shader */
5315     color = getPixelColor(device, 478, 358);
5316     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5317     color = getPixelColor(device, 482, 358);
5318     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5319         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5320     color = getPixelColor(device, 478, 362);
5321     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5322     color = getPixelColor(device, 482, 362);
5323     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5324         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5325
5326     /* 1.3 shader */
5327     color = getPixelColor(device, 478, 118);
5328     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5329     color = getPixelColor(device, 482, 118);
5330     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5332     color = getPixelColor(device, 478, 122);
5333     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5334     color = getPixelColor(device, 482, 122);
5335     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5336         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5337
5338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5340
5341     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5342     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5343     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5344     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5345     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5346     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5347
5348     hr = IDirect3DDevice9_BeginScene(device);
5349     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5350     if(SUCCEEDED(hr))
5351     {
5352         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5353         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5354         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5355         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5356
5357         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5358         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5360         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5361
5362         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5363         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5365         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5366
5367         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5368         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5369         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5370         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5371
5372         hr = IDirect3DDevice9_EndScene(device);
5373         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5374     }
5375
5376     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5377     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5378
5379     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5380      * that we swapped the values in c1 and c2 to make the other tests return some color
5381      */
5382     color = getPixelColor(device, 158, 118);
5383     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5384     color = getPixelColor(device, 162, 118);
5385     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5386     color = getPixelColor(device, 158, 122);
5387     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5388     color = getPixelColor(device, 162, 122);
5389     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5390
5391     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5392      * (The Win7 nvidia driver always selects c2)
5393      */
5394     color = getPixelColor(device, 158, 358);
5395     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5396         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5397     color = getPixelColor(device, 162, 358);
5398     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5399         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5400     color = getPixelColor(device, 158, 362);
5401     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5402         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5403     color = getPixelColor(device, 162, 362);
5404     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5405         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5406
5407     /* 1.2 shader */
5408     color = getPixelColor(device, 478, 358);
5409     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5410         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5411     color = getPixelColor(device, 482, 358);
5412     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5413         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5414     color = getPixelColor(device, 478, 362);
5415     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5416         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5417     color = getPixelColor(device, 482, 362);
5418     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5419         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5420
5421     /* 1.3 shader */
5422     color = getPixelColor(device, 478, 118);
5423     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5424         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5425     color = getPixelColor(device, 482, 118);
5426     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5427         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5428     color = getPixelColor(device, 478, 122);
5429     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5430         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5431     color = getPixelColor(device, 482, 122);
5432     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5433         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5434
5435     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5436     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5437
5438     IDirect3DPixelShader9_Release(shader_14_coissue);
5439     IDirect3DPixelShader9_Release(shader_13_coissue);
5440     IDirect3DPixelShader9_Release(shader_12_coissue);
5441     IDirect3DPixelShader9_Release(shader_11_coissue);
5442     IDirect3DPixelShader9_Release(shader_14);
5443     IDirect3DPixelShader9_Release(shader_13);
5444     IDirect3DPixelShader9_Release(shader_12);
5445     IDirect3DPixelShader9_Release(shader_11);
5446 }
5447
5448 static void nested_loop_test(IDirect3DDevice9 *device) {
5449     const DWORD shader_code[] = {
5450         0xffff0300,                                                             /* ps_3_0               */
5451         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5452         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5453         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5454         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5455         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5456         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5457         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5458         0x0000001d,                                                             /* endloop              */
5459         0x0000001d,                                                             /* endloop              */
5460         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5461         0x0000ffff                                                              /* end                  */
5462     };
5463     const DWORD vshader_code[] = {
5464         0xfffe0300,                                                             /* vs_3_0               */
5465         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5466         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5467         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5468         0x0000ffff                                                              /* end                  */
5469     };
5470     IDirect3DPixelShader9 *shader;
5471     IDirect3DVertexShader9 *vshader;
5472     HRESULT hr;
5473     DWORD color;
5474     const float quad[] = {
5475         -1.0,   -1.0,   0.1,
5476          1.0,   -1.0,   0.1,
5477         -1.0,    1.0,   0.1,
5478          1.0,    1.0,   0.1
5479     };
5480
5481     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5482     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5483     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5484     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5485     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5486     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5487     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5488     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5489     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5490     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5491     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5492     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5493
5494     hr = IDirect3DDevice9_BeginScene(device);
5495     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5496     if(SUCCEEDED(hr))
5497     {
5498         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5499         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5500         hr = IDirect3DDevice9_EndScene(device);
5501         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5502     }
5503
5504     color = getPixelColor(device, 360, 240);
5505     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5506        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5507
5508     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5509     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5510
5511     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5512     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5513     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5514     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5515     IDirect3DPixelShader9_Release(shader);
5516     IDirect3DVertexShader9_Release(vshader);
5517 }
5518
5519 struct varying_test_struct
5520 {
5521     const DWORD             *shader_code;
5522     IDirect3DPixelShader9   *shader;
5523     DWORD                   color, color_rhw;
5524     const char              *name;
5525     BOOL                    todo, todo_rhw;
5526 };
5527
5528 struct hugeVertex
5529 {
5530     float pos_x,        pos_y,      pos_z,      rhw;
5531     float weight_1,     weight_2,   weight_3,   weight_4;
5532     float index_1,      index_2,    index_3,    index_4;
5533     float normal_1,     normal_2,   normal_3,   normal_4;
5534     float fog_1,        fog_2,      fog_3,      fog_4;
5535     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5536     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5537     float binormal_1,   binormal_2, binormal_3, binormal_4;
5538     float depth_1,      depth_2,    depth_3,    depth_4;
5539     DWORD diffuse, specular;
5540 };
5541
5542 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5543     /* dcl_position: fails to compile */
5544     const DWORD blendweight_code[] = {
5545         0xffff0300,                             /* ps_3_0                   */
5546         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5547         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5548         0x0000ffff                              /* end                      */
5549     };
5550     const DWORD blendindices_code[] = {
5551         0xffff0300,                             /* ps_3_0                   */
5552         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5553         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5554         0x0000ffff                              /* end                      */
5555     };
5556     const DWORD normal_code[] = {
5557         0xffff0300,                             /* ps_3_0                   */
5558         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5559         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5560         0x0000ffff                              /* end                      */
5561     };
5562     /* psize: fails? */
5563     const DWORD texcoord0_code[] = {
5564         0xffff0300,                             /* ps_3_0                   */
5565         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5566         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5567         0x0000ffff                              /* end                      */
5568     };
5569     const DWORD tangent_code[] = {
5570         0xffff0300,                             /* ps_3_0                   */
5571         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5572         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5573         0x0000ffff                              /* end                      */
5574     };
5575     const DWORD binormal_code[] = {
5576         0xffff0300,                             /* ps_3_0                   */
5577         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5578         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5579         0x0000ffff                              /* end                      */
5580     };
5581     /* tessfactor: fails */
5582     /* positiont: fails */
5583     const DWORD color_code[] = {
5584         0xffff0300,                             /* ps_3_0                   */
5585         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5586         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5587         0x0000ffff                              /* end                      */
5588     };
5589     const DWORD fog_code[] = {
5590         0xffff0300,                             /* ps_3_0                   */
5591         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5592         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5593         0x0000ffff                              /* end                      */
5594     };
5595     const DWORD depth_code[] = {
5596         0xffff0300,                             /* ps_3_0                   */
5597         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5598         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5599         0x0000ffff                              /* end                      */
5600     };
5601     const DWORD specular_code[] = {
5602         0xffff0300,                             /* ps_3_0                   */
5603         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5604         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5605         0x0000ffff                              /* end                      */
5606     };
5607     /* sample: fails */
5608
5609     struct varying_test_struct tests[] = {
5610        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5611        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5612        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5613        /* Why does dx not forward the texcoord? */
5614        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5615        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5616        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5617        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5618        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5619        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5620        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5621     };
5622     /* Declare a monster vertex type :-) */
5623     static const D3DVERTEXELEMENT9 decl_elements[] = {
5624         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5625         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5626         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5627         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5628         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5629         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5630         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5631         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5632         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5633         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5634         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5635         D3DDECL_END()
5636     };
5637     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5638         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5639         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5640         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5641         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5642         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5643         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5644         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5645         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5646         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5647         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5648         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5649         D3DDECL_END()
5650     };
5651     struct hugeVertex data[4] = {
5652         {
5653             -1.0,   -1.0,   0.1,    1.0,
5654              0.1,    0.1,   0.1,    0.1,
5655              0.2,    0.2,   0.2,    0.2,
5656              0.3,    0.3,   0.3,    0.3,
5657              0.4,    0.4,   0.4,    0.4,
5658              0.50,   0.55,  0.55,   0.55,
5659              0.6,    0.6,   0.6,    0.7,
5660              0.7,    0.7,   0.7,    0.6,
5661              0.8,    0.8,   0.8,    0.8,
5662              0xe6e6e6e6, /* 0.9 * 256 */
5663              0x224488ff  /* Nothing special */
5664         },
5665         {
5666              1.0,   -1.0,   0.1,    1.0,
5667              0.1,    0.1,   0.1,    0.1,
5668              0.2,    0.2,   0.2,    0.2,
5669              0.3,    0.3,   0.3,    0.3,
5670              0.4,    0.4,   0.4,    0.4,
5671              0.50,   0.55,  0.55,   0.55,
5672              0.6,    0.6,   0.6,    0.7,
5673              0.7,    0.7,   0.7,    0.6,
5674              0.8,    0.8,   0.8,    0.8,
5675              0xe6e6e6e6, /* 0.9 * 256 */
5676              0x224488ff /* Nothing special */
5677         },
5678         {
5679             -1.0,    1.0,   0.1,    1.0,
5680              0.1,    0.1,   0.1,    0.1,
5681              0.2,    0.2,   0.2,    0.2,
5682              0.3,    0.3,   0.3,    0.3,
5683              0.4,    0.4,   0.4,    0.4,
5684              0.50,   0.55,  0.55,   0.55,
5685              0.6,    0.6,   0.6,    0.7,
5686              0.7,    0.7,   0.7,    0.6,
5687              0.8,    0.8,   0.8,    0.8,
5688              0xe6e6e6e6, /* 0.9 * 256 */
5689              0x224488ff /* Nothing special */
5690         },
5691         {
5692              1.0,    1.0,   0.1,    1.0,
5693              0.1,    0.1,   0.1,    0.1,
5694              0.2,    0.2,   0.2,    0.2,
5695              0.3,    0.3,   0.3,    0.3,
5696              0.4,    0.4,   0.4,    0.4,
5697              0.50,   0.55,  0.55,   0.55,
5698              0.6,    0.6,   0.6,    0.7,
5699              0.7,    0.7,   0.7,    0.6,
5700              0.8,    0.8,   0.8,    0.8,
5701              0xe6e6e6e6, /* 0.9 * 256 */
5702              0x224488ff /* Nothing special */
5703         },
5704     };
5705     struct hugeVertex data2[4];
5706     IDirect3DVertexDeclaration9 *decl;
5707     IDirect3DVertexDeclaration9 *decl2;
5708     HRESULT hr;
5709     unsigned int i;
5710     DWORD color, r, g, b, r_e, g_e, b_e;
5711     BOOL drawok;
5712
5713     memcpy(data2, data, sizeof(data2));
5714     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5715     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5716     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5717     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5718
5719     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5720     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5721     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5722     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5723     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5724     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5725
5726     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5727     {
5728         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5729         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5730            tests[i].name, hr);
5731     }
5732
5733     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5734     {
5735         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5736         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5737
5738         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5739         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5740
5741         hr = IDirect3DDevice9_BeginScene(device);
5742         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5743         drawok = FALSE;
5744         if(SUCCEEDED(hr))
5745         {
5746             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5747             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5748             drawok = SUCCEEDED(hr);
5749             hr = IDirect3DDevice9_EndScene(device);
5750             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5751         }
5752
5753         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5754          * the failure and do not check the color if it failed
5755          */
5756         if(!drawok) {
5757             continue;
5758         }
5759
5760         color = getPixelColor(device, 360, 240);
5761         r = color & 0x00ff0000 >> 16;
5762         g = color & 0x0000ff00 >>  8;
5763         b = color & 0x000000ff;
5764         r_e = tests[i].color & 0x00ff0000 >> 16;
5765         g_e = tests[i].color & 0x0000ff00 >>  8;
5766         b_e = tests[i].color & 0x000000ff;
5767
5768         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5769         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5770
5771         if(tests[i].todo) {
5772             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5773                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5774                          tests[i].name, color, tests[i].color);
5775         } else {
5776             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5777                "Test %s returned color 0x%08x, expected 0x%08x\n",
5778                tests[i].name, color, tests[i].color);
5779         }
5780     }
5781
5782     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5783     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5784     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5785     {
5786         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5787         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5788
5789         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5790         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5791
5792         hr = IDirect3DDevice9_BeginScene(device);
5793         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5794         if(SUCCEEDED(hr))
5795         {
5796             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5797             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5798             hr = IDirect3DDevice9_EndScene(device);
5799             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5800         }
5801
5802         color = getPixelColor(device, 360, 240);
5803         r = color & 0x00ff0000 >> 16;
5804         g = color & 0x0000ff00 >>  8;
5805         b = color & 0x000000ff;
5806         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5807         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5808         b_e = tests[i].color_rhw & 0x000000ff;
5809
5810         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5811         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5812
5813         if(tests[i].todo_rhw) {
5814             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5815              * pipeline
5816              */
5817             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5818                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5819                          tests[i].name, color, tests[i].color_rhw);
5820         } else {
5821             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5822                "Test %s returned color 0x%08x, expected 0x%08x\n",
5823                tests[i].name, color, tests[i].color_rhw);
5824         }
5825     }
5826
5827     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5828     {
5829         IDirect3DPixelShader9_Release(tests[i].shader);
5830     }
5831
5832     IDirect3DVertexDeclaration9_Release(decl2);
5833     IDirect3DVertexDeclaration9_Release(decl);
5834 }
5835
5836 static void test_compare_instructions(IDirect3DDevice9 *device)
5837 {
5838     DWORD shader_sge_vec_code[] = {
5839         0xfffe0101,                                         /* vs_1_1                   */
5840         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5841         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5842         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5843         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5844         0x0000ffff                                          /* end                      */
5845     };
5846     DWORD shader_slt_vec_code[] = {
5847         0xfffe0101,                                         /* vs_1_1                   */
5848         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5849         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5850         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5851         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5852         0x0000ffff                                          /* end                      */
5853     };
5854     DWORD shader_sge_scalar_code[] = {
5855         0xfffe0101,                                         /* vs_1_1                   */
5856         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5857         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5858         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5859         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5860         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5861         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5862         0x0000ffff                                          /* end                      */
5863     };
5864     DWORD shader_slt_scalar_code[] = {
5865         0xfffe0101,                                         /* vs_1_1                   */
5866         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5867         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5868         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5869         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5870         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5871         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5872         0x0000ffff                                          /* end                      */
5873     };
5874     IDirect3DVertexShader9 *shader_sge_vec;
5875     IDirect3DVertexShader9 *shader_slt_vec;
5876     IDirect3DVertexShader9 *shader_sge_scalar;
5877     IDirect3DVertexShader9 *shader_slt_scalar;
5878     HRESULT hr, color;
5879     float quad1[] =  {
5880         -1.0,   -1.0,   0.1,
5881          0.0,   -1.0,   0.1,
5882         -1.0,    0.0,   0.1,
5883          0.0,    0.0,   0.1
5884     };
5885     float quad2[] =  {
5886          0.0,   -1.0,   0.1,
5887          1.0,   -1.0,   0.1,
5888          0.0,    0.0,   0.1,
5889          1.0,    0.0,   0.1
5890     };
5891     float quad3[] =  {
5892         -1.0,    0.0,   0.1,
5893          0.0,    0.0,   0.1,
5894         -1.0,    1.0,   0.1,
5895          0.0,    1.0,   0.1
5896     };
5897     float quad4[] =  {
5898          0.0,    0.0,   0.1,
5899          1.0,    0.0,   0.1,
5900          0.0,    1.0,   0.1,
5901          1.0,    1.0,   0.1
5902     };
5903     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5904     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5905
5906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5907     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5908
5909     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5910     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5911     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5912     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5913     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5914     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5915     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5916     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5917     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5918     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5919     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5920     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5921     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5922     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5923
5924     hr = IDirect3DDevice9_BeginScene(device);
5925     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5926     if(SUCCEEDED(hr))
5927     {
5928         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5929         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5930         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5931         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5932
5933         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5934         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5935         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5936         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5937
5938         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5939         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5941         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5942
5943         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5944         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5945
5946         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5947         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5948         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5949         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5950
5951         hr = IDirect3DDevice9_EndScene(device);
5952         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5953     }
5954
5955     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5956     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5957
5958     color = getPixelColor(device, 160, 360);
5959     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5960     color = getPixelColor(device, 480, 360);
5961     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5962     color = getPixelColor(device, 160, 120);
5963     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5964     color = getPixelColor(device, 480, 160);
5965     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5966
5967     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5968     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5969
5970     IDirect3DVertexShader9_Release(shader_sge_vec);
5971     IDirect3DVertexShader9_Release(shader_slt_vec);
5972     IDirect3DVertexShader9_Release(shader_sge_scalar);
5973     IDirect3DVertexShader9_Release(shader_slt_scalar);
5974 }
5975
5976 static void test_vshader_input(IDirect3DDevice9 *device)
5977 {
5978     DWORD swapped_shader_code_3[] = {
5979         0xfffe0300,                                         /* vs_3_0               */
5980         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5981         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5982         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5983         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5984         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5985         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5986         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5987         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5988         0x0000ffff                                          /* end                  */
5989     };
5990     DWORD swapped_shader_code_1[] = {
5991         0xfffe0101,                                         /* vs_1_1               */
5992         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5993         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5994         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5995         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5996         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5997         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5998         0x0000ffff                                          /* end                  */
5999     };
6000     DWORD swapped_shader_code_2[] = {
6001         0xfffe0200,                                         /* vs_2_0               */
6002         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6003         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6004         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6005         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6006         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6007         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6008         0x0000ffff                                          /* end                  */
6009     };
6010     DWORD texcoord_color_shader_code_3[] = {
6011         0xfffe0300,                                         /* vs_3_0               */
6012         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6013         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6014         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6015         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6016         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6017         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6018         0x0000ffff                                          /* end                  */
6019     };
6020     DWORD texcoord_color_shader_code_2[] = {
6021         0xfffe0200,                                         /* vs_2_0               */
6022         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6023         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6024         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6025         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6026         0x0000ffff                                          /* end                  */
6027     };
6028     DWORD texcoord_color_shader_code_1[] = {
6029         0xfffe0101,                                         /* vs_1_1               */
6030         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6031         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6032         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6033         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6034         0x0000ffff                                          /* end                  */
6035     };
6036     DWORD color_color_shader_code_3[] = {
6037         0xfffe0300,                                         /* vs_3_0               */
6038         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6039         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6040         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6041         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6042         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6043         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6044         0x0000ffff                                          /* end                  */
6045     };
6046     DWORD color_color_shader_code_2[] = {
6047         0xfffe0200,                                         /* vs_2_0               */
6048         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6049         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6050         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6051         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6052         0x0000ffff                                          /* end                  */
6053     };
6054     DWORD color_color_shader_code_1[] = {
6055         0xfffe0101,                                         /* vs_1_1               */
6056         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6057         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6058         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6059         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6060         0x0000ffff                                          /* end                  */
6061     };
6062     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6063     HRESULT hr;
6064     DWORD color;
6065     float quad1[] =  {
6066         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6067          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6068         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6069          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6070     };
6071     float quad2[] =  {
6072          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6073          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6074          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6075          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6076     };
6077     float quad3[] =  {
6078         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6079          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6080         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6081          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6082     };
6083     float quad4[] =  {
6084          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6085          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6086          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6087          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6088     };
6089     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6090         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6091         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6092         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6093         D3DDECL_END()
6094     };
6095     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6096         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6097         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6098         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6099         D3DDECL_END()
6100     };
6101     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6102         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6103         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6104         D3DDECL_END()
6105     };
6106     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6107         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6108         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6109         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6110         D3DDECL_END()
6111     };
6112     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6113         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6114         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6115         D3DDECL_END()
6116     };
6117     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6118         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6119         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6120         D3DDECL_END()
6121     };
6122     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6123         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6124         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6125         D3DDECL_END()
6126     };
6127     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6128         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6129         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6130         D3DDECL_END()
6131     };
6132     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6133     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6134     unsigned int i;
6135     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6136     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6137
6138     struct vertex quad1_color[] =  {
6139        {-1.0,   -1.0,   0.1,    0x00ff8040},
6140        { 0.0,   -1.0,   0.1,    0x00ff8040},
6141        {-1.0,    0.0,   0.1,    0x00ff8040},
6142        { 0.0,    0.0,   0.1,    0x00ff8040}
6143     };
6144     struct vertex quad2_color[] =  {
6145        { 0.0,   -1.0,   0.1,    0x00ff8040},
6146        { 1.0,   -1.0,   0.1,    0x00ff8040},
6147        { 0.0,    0.0,   0.1,    0x00ff8040},
6148        { 1.0,    0.0,   0.1,    0x00ff8040}
6149     };
6150     struct vertex quad3_color[] =  {
6151        {-1.0,    0.0,   0.1,    0x00ff8040},
6152        { 0.0,    0.0,   0.1,    0x00ff8040},
6153        {-1.0,    1.0,   0.1,    0x00ff8040},
6154        { 0.0,    1.0,   0.1,    0x00ff8040}
6155     };
6156     float quad4_color[] =  {
6157          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6158          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6159          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6160          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6161     };
6162
6163     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6164     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6165     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6166     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6167     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6168     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6169     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6170     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6171
6172     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6173     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6174     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6175     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6176     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6177     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6178     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6179     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6180
6181     for(i = 1; i <= 3; i++) {
6182         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6183         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6184         if(i == 3) {
6185             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6186             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6187         } else if(i == 2){
6188             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6189             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6190         } else if(i == 1) {
6191             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6192             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6193         }
6194
6195         hr = IDirect3DDevice9_BeginScene(device);
6196         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6197         if(SUCCEEDED(hr))
6198         {
6199             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6200             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6201
6202             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6203             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6204             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6205             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6206
6207             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6208             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6209             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6210             if(i == 3 || i == 2) {
6211                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6212             } else if(i == 1) {
6213                 /* Succeeds or fails, depending on SW or HW vertex processing */
6214                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6215             }
6216
6217             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6218             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6219             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6220             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6221
6222             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6223             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6224             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6225             if(i == 3 || i == 2) {
6226                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6227             } else if(i == 1) {
6228                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6229             }
6230
6231             hr = IDirect3DDevice9_EndScene(device);
6232             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6233         }
6234
6235         if(i == 3 || i == 2) {
6236             color = getPixelColor(device, 160, 360);
6237             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6238                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6239
6240             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6241             color = getPixelColor(device, 480, 360);
6242             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6243                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6244             color = getPixelColor(device, 160, 120);
6245             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6246             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6247                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6248
6249             color = getPixelColor(device, 480, 160);
6250             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6251         } else if(i == 1) {
6252             color = getPixelColor(device, 160, 360);
6253             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6254                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6255             color = getPixelColor(device, 480, 360);
6256             /* Accept the clear color as well in this case, since SW VP returns an error */
6257             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6258             color = getPixelColor(device, 160, 120);
6259             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6260                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6261             color = getPixelColor(device, 480, 160);
6262             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6263         }
6264
6265         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6266         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6267
6268         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6269         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6270
6271         /* Now find out if the whole streams are re-read, or just the last active value for the
6272          * vertices is used.
6273          */
6274         hr = IDirect3DDevice9_BeginScene(device);
6275         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6276         if(SUCCEEDED(hr))
6277         {
6278             float quad1_modified[] =  {
6279                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6280                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6281                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6282                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6283             };
6284             float quad2_modified[] =  {
6285                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6286                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6287                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6288                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6289             };
6290
6291             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6292             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6293
6294             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6295             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6296             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6297             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6298
6299             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6300             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6301             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6302             if(i == 3 || i == 2) {
6303                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6304             } else if(i == 1) {
6305                 /* Succeeds or fails, depending on SW or HW vertex processing */
6306                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6307             }
6308
6309             hr = IDirect3DDevice9_EndScene(device);
6310             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6311         }
6312
6313         color = getPixelColor(device, 480, 350);
6314         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6315          * as well.
6316          *
6317          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6318          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6319          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6320          * refrast's result.
6321          *
6322          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6323          */
6324         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6325            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6326
6327         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6328         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6329
6330         IDirect3DDevice9_SetVertexShader(device, NULL);
6331         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6332
6333         IDirect3DVertexShader9_Release(swapped_shader);
6334     }
6335
6336     for(i = 1; i <= 3; i++) {
6337         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6338         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6339         if(i == 3) {
6340             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6341             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6342             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6343             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6344         } else if(i == 2){
6345             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6346             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6347             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6348             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6349         } else if(i == 1) {
6350             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6351             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6352             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6353             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6354         }
6355
6356         hr = IDirect3DDevice9_BeginScene(device);
6357         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6358         if(SUCCEEDED(hr))
6359         {
6360             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6361             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6362             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6363             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6364             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6365             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6366
6367             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6368             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6369
6370             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6371             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6372             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6373             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6374             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6375             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6376
6377             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6378             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6379             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6380             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6381             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6382             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6383
6384             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6385             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6386             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6387             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6388
6389             hr = IDirect3DDevice9_EndScene(device);
6390             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6391         }
6392         IDirect3DDevice9_SetVertexShader(device, NULL);
6393         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6394
6395         color = getPixelColor(device, 160, 360);
6396         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6397            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6398         color = getPixelColor(device, 480, 360);
6399         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6400            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6401         color = getPixelColor(device, 160, 120);
6402         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6403            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6404         color = getPixelColor(device, 480, 160);
6405         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6406            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6407
6408         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6409         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6410
6411         IDirect3DVertexShader9_Release(texcoord_color_shader);
6412         IDirect3DVertexShader9_Release(color_color_shader);
6413     }
6414
6415     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6416     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6417     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6418     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6419
6420     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6421     IDirect3DVertexDeclaration9_Release(decl_color_color);
6422     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6423     IDirect3DVertexDeclaration9_Release(decl_color_float);
6424 }
6425
6426 static void srgbtexture_test(IDirect3DDevice9 *device)
6427 {
6428     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6429      * texture stage state to render a quad using that texture.  The resulting
6430      * color components should be 0x36 (~ 0.21), per this formula:
6431      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6432      * This is true where srgb_color > 0.04045.
6433      */
6434     IDirect3D9 *d3d = NULL;
6435     HRESULT hr;
6436     LPDIRECT3DTEXTURE9 texture = NULL;
6437     LPDIRECT3DSURFACE9 surface = NULL;
6438     D3DLOCKED_RECT lr;
6439     DWORD color;
6440     float quad[] = {
6441         -1.0,       1.0,       0.0,     0.0,    0.0,
6442          1.0,       1.0,       0.0,     1.0,    0.0,
6443         -1.0,      -1.0,       0.0,     0.0,    1.0,
6444          1.0,      -1.0,       0.0,     1.0,    1.0,
6445     };
6446
6447
6448     memset(&lr, 0, sizeof(lr));
6449     IDirect3DDevice9_GetDirect3D(device, &d3d);
6450     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6451                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6452                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6453         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6454         goto out;
6455     }
6456
6457     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6458                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6459                                         &texture, NULL);
6460     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6461     if(!texture) {
6462         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6463         goto out;
6464     }
6465     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6466     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6467
6468     fill_surface(surface, 0xff7f7f7f);
6469     IDirect3DSurface9_Release(surface);
6470
6471     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6472     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6473     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6474     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6475
6476     hr = IDirect3DDevice9_BeginScene(device);
6477     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6478     if(SUCCEEDED(hr))
6479     {
6480         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6481         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6482
6483         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6484         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6485
6486
6487         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6488         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6489
6490         hr = IDirect3DDevice9_EndScene(device);
6491         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6492     }
6493
6494     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6495     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6496     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6497     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6498
6499     color = getPixelColor(device, 320, 240);
6500     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6501
6502     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6503     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6504
6505 out:
6506     if(texture) IDirect3DTexture9_Release(texture);
6507     IDirect3D9_Release(d3d);
6508 }
6509
6510 static void shademode_test(IDirect3DDevice9 *device)
6511 {
6512     /* Render a quad and try all of the different fixed function shading models. */
6513     HRESULT hr;
6514     DWORD color0, color1;
6515     DWORD color0_gouraud = 0, color1_gouraud = 0;
6516     DWORD shademode = D3DSHADE_FLAT;
6517     DWORD primtype = D3DPT_TRIANGLESTRIP;
6518     LPVOID data = NULL;
6519     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6520     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6521     UINT i, j;
6522     struct vertex quad_strip[] =
6523     {
6524         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6525         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6526         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6527         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6528     };
6529     struct vertex quad_list[] =
6530     {
6531         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6532         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6533         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6534
6535         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6536         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6537         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6538     };
6539
6540     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6541                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6542     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6543     if (FAILED(hr)) goto bail;
6544
6545     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6546                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6547     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6548     if (FAILED(hr)) goto bail;
6549
6550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6551     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6552
6553     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6554     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6555
6556     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6557     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6558     memcpy(data, quad_strip, sizeof(quad_strip));
6559     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6560     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6561
6562     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6563     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6564     memcpy(data, quad_list, sizeof(quad_list));
6565     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6566     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6567
6568     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6569      * the color fixups we have to do for FLAT shading will be dependent on that. */
6570     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6571     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6572
6573     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6574     for (j=0; j<2; j++) {
6575
6576         /* Inner loop just changes the D3DRS_SHADEMODE */
6577         for (i=0; i<3; i++) {
6578             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6579             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6580
6581             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6582             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6583
6584             hr = IDirect3DDevice9_BeginScene(device);
6585             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6586             if(SUCCEEDED(hr))
6587             {
6588                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6589                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6590
6591                 hr = IDirect3DDevice9_EndScene(device);
6592                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6593             }
6594
6595             /* Sample two spots from the output */
6596             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6597             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6598             switch(shademode) {
6599                 case D3DSHADE_FLAT:
6600                     /* Should take the color of the first vertex of each triangle */
6601                     if (0)
6602                     {
6603                         /* This test depends on EXT_provoking_vertex being
6604                          * available. This extension is currently (20090810)
6605                          * not common enough to let the test fail if it isn't
6606                          * present. */
6607                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6608                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6609                     }
6610                     shademode = D3DSHADE_GOURAUD;
6611                     break;
6612                 case D3DSHADE_GOURAUD:
6613                     /* Should be an interpolated blend */
6614
6615                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6616                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6617                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6618                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6619
6620                     color0_gouraud = color0;
6621                     color1_gouraud = color1;
6622
6623                     shademode = D3DSHADE_PHONG;
6624                     break;
6625                 case D3DSHADE_PHONG:
6626                     /* Should be the same as GOURAUD, since no hardware implements this */
6627                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6628                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6629                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6630                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6631
6632                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6633                             color0_gouraud, color0);
6634                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6635                             color1_gouraud, color1);
6636                     break;
6637             }
6638         }
6639
6640         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6641         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6642
6643         /* Now, do it all over again with a TRIANGLELIST */
6644         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6645         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6646         primtype = D3DPT_TRIANGLELIST;
6647         shademode = D3DSHADE_FLAT;
6648     }
6649
6650 bail:
6651     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6652     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6654     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6655
6656     if (vb_strip)
6657         IDirect3DVertexBuffer9_Release(vb_strip);
6658     if (vb_list)
6659         IDirect3DVertexBuffer9_Release(vb_list);
6660 }
6661
6662 static void alpha_test(IDirect3DDevice9 *device)
6663 {
6664     HRESULT hr;
6665     IDirect3DTexture9 *offscreenTexture;
6666     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6667     DWORD color;
6668
6669     struct vertex quad1[] =
6670     {
6671         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6672         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6673         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6674         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6675     };
6676     struct vertex quad2[] =
6677     {
6678         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6679         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6680         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6681         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6682     };
6683     static const float composite_quad[][5] = {
6684         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6685         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6686         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6687         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6688     };
6689
6690     /* Clear the render target with alpha = 0.5 */
6691     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6692     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6693
6694     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6695     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6696
6697     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6698     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6699     if(!backbuffer) {
6700         goto out;
6701     }
6702
6703     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6704     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6705     if(!offscreen) {
6706         goto out;
6707     }
6708
6709     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6710     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6711
6712     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6713     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6714     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6715     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6716     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6717     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6718     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6719     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6720     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6721     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6722
6723     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6724     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6725     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6726
6727         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6728         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6729         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6730         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6731         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6732         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6733         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6734
6735         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6736         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6737         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6738         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6739         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6740         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6741
6742         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6743          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6744          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6745         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6746         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6747         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6748         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6749
6750         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6751         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6752         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6753         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6754         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6755         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6756
6757         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6758         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6759         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6760         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6761         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6762         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6763
6764         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6765         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6766
6767         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6768          * Disable alpha blending for the final composition
6769          */
6770         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6771         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6772         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6773         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6774
6775         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6776         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6778         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6779         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6780         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6781
6782         hr = IDirect3DDevice9_EndScene(device);
6783         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6784     }
6785
6786     color = getPixelColor(device, 160, 360);
6787     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6788        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6789
6790     color = getPixelColor(device, 160, 120);
6791     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6792        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6793
6794     color = getPixelColor(device, 480, 360);
6795     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6796        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6797
6798     color = getPixelColor(device, 480, 120);
6799     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6800        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6801
6802     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6803
6804     out:
6805     /* restore things */
6806     if(backbuffer) {
6807         IDirect3DSurface9_Release(backbuffer);
6808     }
6809     if(offscreenTexture) {
6810         IDirect3DTexture9_Release(offscreenTexture);
6811     }
6812     if(offscreen) {
6813         IDirect3DSurface9_Release(offscreen);
6814     }
6815 }
6816
6817 struct vertex_shortcolor {
6818     float x, y, z;
6819     unsigned short r, g, b, a;
6820 };
6821 struct vertex_floatcolor {
6822     float x, y, z;
6823     float r, g, b, a;
6824 };
6825
6826 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6827 {
6828     HRESULT hr;
6829     BOOL s_ok, ub_ok, f_ok;
6830     DWORD color, size, i;
6831     void *data;
6832     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6833         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6834         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6835         D3DDECL_END()
6836     };
6837     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6838         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6839         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6840         D3DDECL_END()
6841     };
6842     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6843         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6844         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6845         D3DDECL_END()
6846     };
6847     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6848         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6849         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6850         D3DDECL_END()
6851     };
6852     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6853         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6854         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6855         D3DDECL_END()
6856     };
6857     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6858         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6859         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6860         D3DDECL_END()
6861     };
6862     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6863         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6864         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6865         D3DDECL_END()
6866     };
6867     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6868     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6869     IDirect3DVertexBuffer9 *vb, *vb2;
6870     struct vertex quad1[] =                             /* D3DCOLOR */
6871     {
6872         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6873         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6874         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6875         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6876     };
6877     struct vertex quad2[] =                             /* UBYTE4N */
6878     {
6879         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6880         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6881         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6882         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6883     };
6884     struct vertex_shortcolor quad3[] =                  /* short */
6885     {
6886         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6887         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6888         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6889         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6890     };
6891     struct vertex_floatcolor quad4[] =
6892     {
6893         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6894         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6895         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6896         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6897     };
6898     DWORD colors[] = {
6899         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6900         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6901         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6902         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6903         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6904         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6905         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6906         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6907         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6908         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6909         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6910         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6911         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6912         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6913         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6914         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6915     };
6916     float quads[] = {
6917         -1.0,   -1.0,     0.1,
6918         -1.0,    0.0,     0.1,
6919          0.0,   -1.0,     0.1,
6920          0.0,    0.0,     0.1,
6921
6922          0.0,   -1.0,     0.1,
6923          0.0,    0.0,     0.1,
6924          1.0,   -1.0,     0.1,
6925          1.0,    0.0,     0.1,
6926
6927          0.0,    0.0,     0.1,
6928          0.0,    1.0,     0.1,
6929          1.0,    0.0,     0.1,
6930          1.0,    1.0,     0.1,
6931
6932         -1.0,    0.0,     0.1,
6933         -1.0,    1.0,     0.1,
6934          0.0,    0.0,     0.1,
6935          0.0,    1.0,     0.1
6936     };
6937     struct tvertex quad_transformed[] = {
6938        {  90,    110,     0.1,      2.0,        0x00ffff00},
6939        { 570,    110,     0.1,      2.0,        0x00ffff00},
6940        {  90,    300,     0.1,      2.0,        0x00ffff00},
6941        { 570,    300,     0.1,      2.0,        0x00ffff00}
6942     };
6943     D3DCAPS9 caps;
6944
6945     memset(&caps, 0, sizeof(caps));
6946     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6947     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6948
6949     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6950     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6951
6952     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6953     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6954     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6955     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6956     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6957     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6958     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6959         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6960         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6961         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6962         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6963     } else {
6964         trace("D3DDTCAPS_UBYTE4N not supported\n");
6965         dcl_ubyte_2 = NULL;
6966         dcl_ubyte = NULL;
6967     }
6968     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6969     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6970     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6971     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6972
6973     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6974     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6975                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6976     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6977
6978     hr = IDirect3DDevice9_BeginScene(device);
6979     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6980     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6981     if(SUCCEEDED(hr)) {
6982         if(dcl_color) {
6983             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6984             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6985             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6986             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6987         }
6988
6989         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6990          * accepts them, the nvidia driver accepts them all. All those differences even though we're
6991          * using software vertex processing. Doh!
6992          */
6993         if(dcl_ubyte) {
6994             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6995             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6996             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6997             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6998             ub_ok = SUCCEEDED(hr);
6999         }
7000
7001         if(dcl_short) {
7002             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7003             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7004             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7005             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7006             s_ok = SUCCEEDED(hr);
7007         }
7008
7009         if(dcl_float) {
7010             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7011             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7012             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7013             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7014             f_ok = SUCCEEDED(hr);
7015         }
7016
7017         hr = IDirect3DDevice9_EndScene(device);
7018         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7019     }
7020
7021     if(dcl_short) {
7022         color = getPixelColor(device, 480, 360);
7023         ok(color == 0x000000ff || !s_ok,
7024            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7025     }
7026     if(dcl_ubyte) {
7027         color = getPixelColor(device, 160, 120);
7028         ok(color == 0x0000ffff || !ub_ok,
7029            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7030     }
7031     if(dcl_color) {
7032         color = getPixelColor(device, 160, 360);
7033         ok(color == 0x00ffff00,
7034            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7035     }
7036     if(dcl_float) {
7037         color = getPixelColor(device, 480, 120);
7038         ok(color == 0x00ff0000 || !f_ok,
7039            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7040     }
7041     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7042
7043     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7044      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7045      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7046      * whether the immediate mode code works
7047      */
7048     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7049     hr = IDirect3DDevice9_BeginScene(device);
7050     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7051     if(SUCCEEDED(hr)) {
7052         if(dcl_color) {
7053             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7054             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7055             memcpy(data, quad1, sizeof(quad1));
7056             hr = IDirect3DVertexBuffer9_Unlock(vb);
7057             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7058             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7059             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7060             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7061             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7062             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7063             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7064         }
7065
7066         if(dcl_ubyte) {
7067             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7068             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7069             memcpy(data, quad2, sizeof(quad2));
7070             hr = IDirect3DVertexBuffer9_Unlock(vb);
7071             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7072             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7073             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7074             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7075             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7076             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7077             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7078                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7079             ub_ok = SUCCEEDED(hr);
7080         }
7081
7082         if(dcl_short) {
7083             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7084             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7085             memcpy(data, quad3, sizeof(quad3));
7086             hr = IDirect3DVertexBuffer9_Unlock(vb);
7087             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7088             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7089             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7090             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7091             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7092             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7093             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7094                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7095             s_ok = SUCCEEDED(hr);
7096         }
7097
7098         if(dcl_float) {
7099             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7100             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7101             memcpy(data, quad4, sizeof(quad4));
7102             hr = IDirect3DVertexBuffer9_Unlock(vb);
7103             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7104             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7105             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7106             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7107             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7108             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7109             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7110                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7111             f_ok = SUCCEEDED(hr);
7112         }
7113
7114         hr = IDirect3DDevice9_EndScene(device);
7115         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7116     }
7117
7118     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7119     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7120     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7121     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7122
7123     if(dcl_short) {
7124         color = getPixelColor(device, 480, 360);
7125         ok(color == 0x000000ff || !s_ok,
7126            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7127     }
7128     if(dcl_ubyte) {
7129         color = getPixelColor(device, 160, 120);
7130         ok(color == 0x0000ffff || !ub_ok,
7131            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7132     }
7133     if(dcl_color) {
7134         color = getPixelColor(device, 160, 360);
7135         ok(color == 0x00ffff00,
7136            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7137     }
7138     if(dcl_float) {
7139         color = getPixelColor(device, 480, 120);
7140         ok(color == 0x00ff0000 || !f_ok,
7141            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7142     }
7143     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7144
7145     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7146     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7147
7148     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7149     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7150     memcpy(data, quad_transformed, sizeof(quad_transformed));
7151     hr = IDirect3DVertexBuffer9_Unlock(vb);
7152     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7153
7154     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7155     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7156
7157     hr = IDirect3DDevice9_BeginScene(device);
7158     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7159     if(SUCCEEDED(hr)) {
7160         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7161         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7162         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7163         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7164
7165         hr = IDirect3DDevice9_EndScene(device);
7166         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7167     }
7168
7169     color = getPixelColor(device, 88, 108);
7170     ok(color == 0x000000ff,
7171        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7172     color = getPixelColor(device, 92, 108);
7173     ok(color == 0x000000ff,
7174        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7175     color = getPixelColor(device, 88, 112);
7176     ok(color == 0x000000ff,
7177        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7178     color = getPixelColor(device, 92, 112);
7179     ok(color == 0x00ffff00,
7180        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7181
7182     color = getPixelColor(device, 568, 108);
7183     ok(color == 0x000000ff,
7184        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7185     color = getPixelColor(device, 572, 108);
7186     ok(color == 0x000000ff,
7187        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7188     color = getPixelColor(device, 568, 112);
7189     ok(color == 0x00ffff00,
7190        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7191     color = getPixelColor(device, 572, 112);
7192     ok(color == 0x000000ff,
7193        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7194
7195     color = getPixelColor(device, 88, 298);
7196     ok(color == 0x000000ff,
7197        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7198     color = getPixelColor(device, 92, 298);
7199     ok(color == 0x00ffff00,
7200        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7201     color = getPixelColor(device, 88, 302);
7202     ok(color == 0x000000ff,
7203        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7204     color = getPixelColor(device, 92, 302);
7205     ok(color == 0x000000ff,
7206        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7207
7208     color = getPixelColor(device, 568, 298);
7209     ok(color == 0x00ffff00,
7210        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7211     color = getPixelColor(device, 572, 298);
7212     ok(color == 0x000000ff,
7213        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7214     color = getPixelColor(device, 568, 302);
7215     ok(color == 0x000000ff,
7216        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7217     color = getPixelColor(device, 572, 302);
7218     ok(color == 0x000000ff,
7219        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7220
7221     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7222
7223     /* This test is pointless without those two declarations: */
7224     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7225         skip("color-ubyte switching test declarations aren't supported\n");
7226         goto out;
7227     }
7228
7229     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7230     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7231     memcpy(data, quads, sizeof(quads));
7232     hr = IDirect3DVertexBuffer9_Unlock(vb);
7233     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7234     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7235                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7236     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7237     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7238     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7239     memcpy(data, colors, sizeof(colors));
7240     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7241     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7242
7243     for(i = 0; i < 2; i++) {
7244         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7245         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7246
7247         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7248         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7249         if(i == 0) {
7250             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7251         } else {
7252             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7253         }
7254         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7255
7256         hr = IDirect3DDevice9_BeginScene(device);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7258         ub_ok = FALSE;
7259         if(SUCCEEDED(hr)) {
7260             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7261             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7262             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7263             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7264                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7265             ub_ok = SUCCEEDED(hr);
7266
7267             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7268             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7269             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7270             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7271
7272             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7273             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7274             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7275             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7276                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7277             ub_ok = (SUCCEEDED(hr) && ub_ok);
7278
7279             hr = IDirect3DDevice9_EndScene(device);
7280             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7281         }
7282
7283         if(i == 0) {
7284             color = getPixelColor(device, 480, 360);
7285             ok(color == 0x00ff0000,
7286                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7287             color = getPixelColor(device, 160, 120);
7288             ok(color == 0x00ffffff,
7289                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7290             color = getPixelColor(device, 160, 360);
7291             ok(color == 0x000000ff || !ub_ok,
7292                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7293             color = getPixelColor(device, 480, 120);
7294             ok(color == 0x000000ff || !ub_ok,
7295                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7296         } else {
7297             color = getPixelColor(device, 480, 360);
7298             ok(color == 0x000000ff,
7299                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7300             color = getPixelColor(device, 160, 120);
7301             ok(color == 0x00ffffff,
7302                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7303             color = getPixelColor(device, 160, 360);
7304             ok(color == 0x00ff0000 || !ub_ok,
7305                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7306             color = getPixelColor(device, 480, 120);
7307             ok(color == 0x00ff0000 || !ub_ok,
7308                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7309         }
7310         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7311     }
7312
7313     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7314     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7315     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7316     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7317     IDirect3DVertexBuffer9_Release(vb2);
7318
7319     out:
7320     IDirect3DVertexBuffer9_Release(vb);
7321     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7322     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7323     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7324     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7325     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7326     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7327     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7328 }
7329
7330 struct vertex_float16color {
7331     float x, y, z;
7332     DWORD c1, c2;
7333 };
7334
7335 static void test_vshader_float16(IDirect3DDevice9 *device)
7336 {
7337     HRESULT hr;
7338     DWORD color;
7339     void *data;
7340     static const D3DVERTEXELEMENT9 decl_elements[] = {
7341         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7342         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7343         D3DDECL_END()
7344     };
7345     IDirect3DVertexDeclaration9 *vdecl = NULL;
7346     IDirect3DVertexBuffer9 *buffer = NULL;
7347     IDirect3DVertexShader9 *shader;
7348     DWORD shader_code[] = {
7349         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7350         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7351         0x90e40001, 0x0000ffff
7352     };
7353     struct vertex_float16color quad[] = {
7354         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7355         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7356         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7357         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7358
7359         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7360         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7361         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7362         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7363
7364         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7365         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7366         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7367         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7368
7369         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7370         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7371         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7372         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7373     };
7374
7375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7377
7378     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7379     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7380     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7381     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7382     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7383     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7384
7385     hr = IDirect3DDevice9_BeginScene(device);
7386     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7387     if(SUCCEEDED(hr)) {
7388         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7389         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7390         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7391         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7392         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7393         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7395         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7396         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7397         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7398
7399         hr = IDirect3DDevice9_EndScene(device);
7400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7401     }
7402     color = getPixelColor(device, 480, 360);
7403     ok(color == 0x00ff0000,
7404        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7405     color = getPixelColor(device, 160, 120);
7406     ok(color == 0x00000000,
7407        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7408     color = getPixelColor(device, 160, 360);
7409     ok(color == 0x0000ff00,
7410        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7411     color = getPixelColor(device, 480, 120);
7412     ok(color == 0x000000ff,
7413        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7414     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7415
7416     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7417     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7418
7419     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7420                                              D3DPOOL_MANAGED, &buffer, NULL);
7421     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7422     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7423     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7424     memcpy(data, quad, sizeof(quad));
7425     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7426     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7427     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7428     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7429
7430     hr = IDirect3DDevice9_BeginScene(device);
7431     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7432     if(SUCCEEDED(hr)) {
7433             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7434             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7435             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7436             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7437             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7438             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7439             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7440             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7441
7442             hr = IDirect3DDevice9_EndScene(device);
7443             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7444     }
7445
7446     color = getPixelColor(device, 480, 360);
7447     ok(color == 0x00ff0000,
7448        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7449     color = getPixelColor(device, 160, 120);
7450     ok(color == 0x00000000,
7451        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7452     color = getPixelColor(device, 160, 360);
7453     ok(color == 0x0000ff00,
7454        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7455     color = getPixelColor(device, 480, 120);
7456     ok(color == 0x000000ff,
7457        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7458     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7459
7460     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7461     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7462     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7463     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7464     IDirect3DDevice9_SetVertexShader(device, NULL);
7465     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7466
7467     IDirect3DVertexDeclaration9_Release(vdecl);
7468     IDirect3DVertexShader9_Release(shader);
7469     IDirect3DVertexBuffer9_Release(buffer);
7470 }
7471
7472 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7473 {
7474     D3DCAPS9 caps;
7475     IDirect3DTexture9 *texture;
7476     HRESULT hr;
7477     D3DLOCKED_RECT rect;
7478     unsigned int x, y;
7479     DWORD *dst, color;
7480     const float quad[] = {
7481         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7482          1.0,   -1.0,   0.1,    1.2,   -0.2,
7483         -1.0,    1.0,   0.1,   -0.2,    1.2,
7484          1.0,    1.0,   0.1,    1.2,    1.2
7485     };
7486     memset(&caps, 0, sizeof(caps));
7487
7488     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7489     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7490     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7491         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7492         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7493            "Card has conditional NP2 support without power of two restriction set\n");
7494         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7495         return;
7496     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7497         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7498         return;
7499     }
7500
7501     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7502     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7503
7504     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7506
7507     memset(&rect, 0, sizeof(rect));
7508     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7509     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7510     for(y = 0; y < 10; y++) {
7511         for(x = 0; x < 10; x++) {
7512             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7513             if(x == 0 || x == 9 || y == 0 || y == 9) {
7514                 *dst = 0x00ff0000;
7515             } else {
7516                 *dst = 0x000000ff;
7517             }
7518         }
7519     }
7520     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7521     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7522
7523     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7524     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7525     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7526     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7527     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7528     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7529     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7530     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7531
7532     hr = IDirect3DDevice9_BeginScene(device);
7533     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7534     if(SUCCEEDED(hr)) {
7535         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7536         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7537
7538         hr = IDirect3DDevice9_EndScene(device);
7539         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7540     }
7541
7542     color = getPixelColor(device,    1,  1);
7543     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7544     color = getPixelColor(device, 639, 479);
7545     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7546
7547     color = getPixelColor(device, 135, 101);
7548     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7549     color = getPixelColor(device, 140, 101);
7550     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7551     color = getPixelColor(device, 135, 105);
7552     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7553     color = getPixelColor(device, 140, 105);
7554     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7555
7556     color = getPixelColor(device, 135, 376);
7557     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7558     color = getPixelColor(device, 140, 376);
7559     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7560     color = getPixelColor(device, 135, 379);
7561     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7562     color = getPixelColor(device, 140, 379);
7563     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7564
7565     color = getPixelColor(device, 500, 101);
7566     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7567     color = getPixelColor(device, 504, 101);
7568     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7569     color = getPixelColor(device, 500, 105);
7570     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7571     color = getPixelColor(device, 504, 105);
7572     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7573
7574     color = getPixelColor(device, 500, 376);
7575     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7576     color = getPixelColor(device, 504, 376);
7577     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7578     color = getPixelColor(device, 500, 380);
7579     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7580     color = getPixelColor(device, 504, 380);
7581     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7582
7583     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7584
7585     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7586     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7587     IDirect3DTexture9_Release(texture);
7588 }
7589
7590 static void vFace_register_test(IDirect3DDevice9 *device)
7591 {
7592     HRESULT hr;
7593     DWORD color;
7594     const DWORD shader_code[] = {
7595         0xffff0300,                                                             /* ps_3_0                     */
7596         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7597         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7598         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7599         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7600         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7601         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7602         0x0000ffff                                                              /* END                        */
7603     };
7604     const DWORD vshader_code[] = {
7605         0xfffe0300,                                                             /* vs_3_0               */
7606         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7607         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7608         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7609         0x0000ffff                                                              /* end                  */
7610     };
7611     IDirect3DPixelShader9 *shader;
7612     IDirect3DVertexShader9 *vshader;
7613     IDirect3DTexture9 *texture;
7614     IDirect3DSurface9 *surface, *backbuffer;
7615     const float quad[] = {
7616         -1.0,   -1.0,   0.1,
7617          1.0,   -1.0,   0.1,
7618         -1.0,    0.0,   0.1,
7619
7620          1.0,   -1.0,   0.1,
7621          1.0,    0.0,   0.1,
7622         -1.0,    0.0,   0.1,
7623
7624         -1.0,    0.0,   0.1,
7625         -1.0,    1.0,   0.1,
7626          1.0,    0.0,   0.1,
7627
7628          1.0,    0.0,   0.1,
7629         -1.0,    1.0,   0.1,
7630          1.0,    1.0,   0.1,
7631     };
7632     const float blit[] = {
7633          0.0,   -1.0,   0.1,    0.0,    0.0,
7634          1.0,   -1.0,   0.1,    1.0,    0.0,
7635          0.0,    1.0,   0.1,    0.0,    1.0,
7636          1.0,    1.0,   0.1,    1.0,    1.0,
7637     };
7638
7639     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7640     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7641     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7642     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7643     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7644     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7645     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7646     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7647     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7648     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7649     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7650     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7651     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7652     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7653     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7654     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7655
7656     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7657     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7658
7659     hr = IDirect3DDevice9_BeginScene(device);
7660     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7661     if(SUCCEEDED(hr)) {
7662         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7663         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7664         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7665         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7666         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7667         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7668         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7669         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7670         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7672         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7673
7674         /* Blit the texture onto the back buffer to make it visible */
7675         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7676         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7677         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7678         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7679         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7680         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7681         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7682         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7683         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7684         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7685         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7686         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7687
7688         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7689         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7690
7691         hr = IDirect3DDevice9_EndScene(device);
7692         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7693     }
7694
7695     color = getPixelColor(device, 160, 360);
7696     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7697     color = getPixelColor(device, 160, 120);
7698     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7699     color = getPixelColor(device, 480, 360);
7700     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7701     color = getPixelColor(device, 480, 120);
7702     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7703     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7704
7705     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7706     IDirect3DDevice9_SetTexture(device, 0, NULL);
7707     IDirect3DPixelShader9_Release(shader);
7708     IDirect3DVertexShader9_Release(vshader);
7709     IDirect3DSurface9_Release(surface);
7710     IDirect3DSurface9_Release(backbuffer);
7711     IDirect3DTexture9_Release(texture);
7712 }
7713
7714 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7715 {
7716     HRESULT hr;
7717     DWORD color;
7718     int i;
7719     D3DCAPS9 caps;
7720     BOOL L6V5U5_supported = FALSE;
7721     IDirect3DTexture9 *tex1, *tex2;
7722     D3DLOCKED_RECT locked_rect;
7723
7724     static const float quad[][7] = {
7725         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7726         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7727         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7728         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7729     };
7730
7731     static const D3DVERTEXELEMENT9 decl_elements[] = {
7732         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7733         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7734         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7735         D3DDECL_END()
7736     };
7737
7738     /* use asymmetric matrix to test loading */
7739     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7740     float scale, offset;
7741
7742     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7743     IDirect3DTexture9           *texture            = NULL;
7744
7745     memset(&caps, 0, sizeof(caps));
7746     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7747     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7748     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7749         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7750         return;
7751     } else {
7752         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7753          * They report that it is not supported, but after that bump mapping works properly. So just test
7754          * if the format is generally supported, and check the BUMPENVMAP flag
7755          */
7756         IDirect3D9 *d3d9;
7757
7758         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7759         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7760                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7761         L6V5U5_supported = SUCCEEDED(hr);
7762         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7763                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7764         IDirect3D9_Release(d3d9);
7765         if(FAILED(hr)) {
7766             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7767             return;
7768         }
7769     }
7770
7771     /* Generate the textures */
7772     generate_bumpmap_textures(device);
7773
7774     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7775     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7776     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7777     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7778     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7779     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7780     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7781     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7782
7783     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7784     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7785     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7786     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7787     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7788     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7789
7790     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7791     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7792     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7793     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7794     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7795     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7796
7797     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7798     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799
7800     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7801     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7802
7803     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7804     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7805
7806
7807     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7808     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7809     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7810     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7811
7812     hr = IDirect3DDevice9_BeginScene(device);
7813     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7814
7815     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7816     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7817
7818     hr = IDirect3DDevice9_EndScene(device);
7819     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7820
7821     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7822      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7823      * But since testing the color match is not the purpose of the test don't be too picky
7824      */
7825     color = getPixelColor(device, 320-32, 240);
7826     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7827     color = getPixelColor(device, 320+32, 240);
7828     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7829     color = getPixelColor(device, 320, 240-32);
7830     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7831     color = getPixelColor(device, 320, 240+32);
7832     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7833     color = getPixelColor(device, 320, 240);
7834     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7835     color = getPixelColor(device, 320+32, 240+32);
7836     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7837     color = getPixelColor(device, 320-32, 240+32);
7838     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7839     color = getPixelColor(device, 320+32, 240-32);
7840     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7841     color = getPixelColor(device, 320-32, 240-32);
7842     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7843     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7844     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7845
7846     for(i = 0; i < 2; i++) {
7847         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7848         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7849         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7850         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7851         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7852         IDirect3DTexture9_Release(texture); /* To destroy it */
7853     }
7854
7855     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7856         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7857         goto cleanup;
7858     }
7859     if(L6V5U5_supported == FALSE) {
7860         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7861         goto cleanup;
7862     }
7863
7864     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7865     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7866     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7867      * would only make this test more complicated
7868      */
7869     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7870     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7871     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7872     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7873
7874     memset(&locked_rect, 0, sizeof(locked_rect));
7875     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7876     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7877     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7878     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7879     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7880
7881     memset(&locked_rect, 0, sizeof(locked_rect));
7882     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7883     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7884     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7885     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7886     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7887
7888     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7889     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7890     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7891     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7892
7893     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7894     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7895     scale = 2.0;
7896     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7897     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7898     offset = 0.1;
7899     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7900     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7901
7902     hr = IDirect3DDevice9_BeginScene(device);
7903     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7904     if(SUCCEEDED(hr)) {
7905         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7906         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7907         hr = IDirect3DDevice9_EndScene(device);
7908         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7909     }
7910
7911     color = getPixelColor(device, 320, 240);
7912     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7913      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7914      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7915      */
7916     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7917     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7918     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7919
7920     /* Check a result scale factor > 1.0 */
7921     scale = 10;
7922     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7923     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7924     offset = 10;
7925     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7926     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7927
7928     hr = IDirect3DDevice9_BeginScene(device);
7929     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7930     if(SUCCEEDED(hr)) {
7931         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7932         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7933         hr = IDirect3DDevice9_EndScene(device);
7934         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7935     }
7936     color = getPixelColor(device, 320, 240);
7937     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7938     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7939     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7940
7941     /* Check clamping in the scale factor calculation */
7942     scale = 1000;
7943     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7944     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7945     offset = -1;
7946     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7947     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7948
7949     hr = IDirect3DDevice9_BeginScene(device);
7950     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7951     if(SUCCEEDED(hr)) {
7952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7953         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7954         hr = IDirect3DDevice9_EndScene(device);
7955         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7956     }
7957     color = getPixelColor(device, 320, 240);
7958     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7959     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7960     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7961
7962     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7963     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7964     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7965     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7966
7967     IDirect3DTexture9_Release(tex1);
7968     IDirect3DTexture9_Release(tex2);
7969
7970 cleanup:
7971     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7972     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7973     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7974     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7975
7976     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7977     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7978     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7979 }
7980
7981 static void stencil_cull_test(IDirect3DDevice9 *device) {
7982     HRESULT hr;
7983     IDirect3DSurface9 *depthstencil = NULL;
7984     D3DSURFACE_DESC desc;
7985     float quad1[] = {
7986         -1.0,   -1.0,   0.1,
7987          0.0,   -1.0,   0.1,
7988         -1.0,    0.0,   0.1,
7989          0.0,    0.0,   0.1,
7990     };
7991     float quad2[] = {
7992          0.0,   -1.0,   0.1,
7993          1.0,   -1.0,   0.1,
7994          0.0,    0.0,   0.1,
7995          1.0,    0.0,   0.1,
7996     };
7997     float quad3[] = {
7998         0.0,    0.0,   0.1,
7999         1.0,    0.0,   0.1,
8000         0.0,    1.0,   0.1,
8001         1.0,    1.0,   0.1,
8002     };
8003     float quad4[] = {
8004         -1.0,    0.0,   0.1,
8005          0.0,    0.0,   0.1,
8006         -1.0,    1.0,   0.1,
8007          0.0,    1.0,   0.1,
8008     };
8009     struct vertex painter[] = {
8010        {-1.0,   -1.0,   0.0,    0x00000000},
8011        { 1.0,   -1.0,   0.0,    0x00000000},
8012        {-1.0,    1.0,   0.0,    0x00000000},
8013        { 1.0,    1.0,   0.0,    0x00000000},
8014     };
8015     WORD indices_cw[]  = {0, 1, 3};
8016     WORD indices_ccw[] = {0, 2, 3};
8017     unsigned int i;
8018     DWORD color;
8019
8020     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8021     if(depthstencil == NULL) {
8022         skip("No depth stencil buffer\n");
8023         return;
8024     }
8025     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8026     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8027     IDirect3DSurface9_Release(depthstencil);
8028     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8029         skip("No 4 or 8 bit stencil surface\n");
8030         return;
8031     }
8032
8033     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8034     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8035     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8036
8037     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8038     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8039     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8040     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8041     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8042     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8043     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8044     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8045
8046     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8047     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8049     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8051     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8052
8053     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8054     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8055     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8056     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8057
8058     /* First pass: Fill the stencil buffer with some values... */
8059     hr = IDirect3DDevice9_BeginScene(device);
8060     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8061     if(SUCCEEDED(hr))
8062     {
8063         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8064         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8065         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8066                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8067         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8068         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8069                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8070         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8071
8072         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8073         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8075         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8076         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8077                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8078         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8079         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8080                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8081         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8082
8083         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8084         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8085         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8086                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8087         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8088         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8089                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8090         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8091
8092         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8093         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8094         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8095                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8096         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8097         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8098                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8099         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8100
8101         hr = IDirect3DDevice9_EndScene(device);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8103     }
8104
8105     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8106     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8107     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8109     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8110     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8111     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8113     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8115     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8116     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8117     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8118
8119     /* 2nd pass: Make the stencil values visible */
8120     hr = IDirect3DDevice9_BeginScene(device);
8121     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8122     if(SUCCEEDED(hr))
8123     {
8124         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8125         for(i = 0; i < 16; i++) {
8126             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8127             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128
8129             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8130             painter[1].diffuse = (i * 16);
8131             painter[2].diffuse = (i * 16);
8132             painter[3].diffuse = (i * 16);
8133             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8134             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8135         }
8136         hr = IDirect3DDevice9_EndScene(device);
8137         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8138     }
8139
8140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8141     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8142
8143     color = getPixelColor(device, 160, 420);
8144     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8145     color = getPixelColor(device, 160, 300);
8146     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8147
8148     color = getPixelColor(device, 480, 420);
8149     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8150     color = getPixelColor(device, 480, 300);
8151     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8152
8153     color = getPixelColor(device, 160, 180);
8154     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8155     color = getPixelColor(device, 160, 60);
8156     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8157
8158     color = getPixelColor(device, 480, 180);
8159     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8160     color = getPixelColor(device, 480, 60);
8161     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8162
8163     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8164     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8165 }
8166
8167 static void vpos_register_test(IDirect3DDevice9 *device)
8168 {
8169     HRESULT hr;
8170     DWORD color;
8171     const DWORD shader_code[] = {
8172     0xffff0300,                                                             /* ps_3_0                     */
8173     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8174     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8175     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8176     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8177     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8178     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8179     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8180     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8181     0x0000ffff                                                              /* end                        */
8182     };
8183     const DWORD shader_frac_code[] = {
8184     0xffff0300,                                                             /* ps_3_0                     */
8185     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8186     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8187     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8188     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8189     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8190     0x0000ffff                                                              /* end                        */
8191     };
8192     const DWORD vshader_code[] = {
8193         0xfffe0300,                                                             /* vs_3_0               */
8194         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8195         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8196         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8197         0x0000ffff                                                              /* end                  */
8198     };
8199     IDirect3DVertexShader9 *vshader;
8200     IDirect3DPixelShader9 *shader, *shader_frac;
8201     IDirect3DSurface9 *surface = NULL, *backbuffer;
8202     const float quad[] = {
8203         -1.0,   -1.0,   0.1,    0.0,    0.0,
8204          1.0,   -1.0,   0.1,    1.0,    0.0,
8205         -1.0,    1.0,   0.1,    0.0,    1.0,
8206          1.0,    1.0,   0.1,    1.0,    1.0,
8207     };
8208     D3DLOCKED_RECT lr;
8209     float constant[4] = {1.0, 0.0, 320, 240};
8210     DWORD *pos;
8211
8212     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8213     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8214     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8215     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8216     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8217     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8218     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8219     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8220     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8221     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8222     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8223     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8224     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8225     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8226     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8227     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8228
8229     hr = IDirect3DDevice9_BeginScene(device);
8230     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8231     if(SUCCEEDED(hr)) {
8232         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8233         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8235         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8236         hr = IDirect3DDevice9_EndScene(device);
8237         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8238     }
8239
8240     /* This has to be pixel exact */
8241     color = getPixelColor(device, 319, 239);
8242     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8243     color = getPixelColor(device, 320, 239);
8244     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8245     color = getPixelColor(device, 319, 240);
8246     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8247     color = getPixelColor(device, 320, 240);
8248     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8249     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8250
8251     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8252                                              &surface, NULL);
8253     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8254     hr = IDirect3DDevice9_BeginScene(device);
8255     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8256     if(SUCCEEDED(hr)) {
8257         constant[2] = 16; constant[3] = 16;
8258         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8259         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8260         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8261         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8262         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8263         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8264         hr = IDirect3DDevice9_EndScene(device);
8265         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8266     }
8267     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8268     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8269
8270     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8271     color = *pos & 0x00ffffff;
8272     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8273     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8274     color = *pos & 0x00ffffff;
8275     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8276     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8277     color = *pos & 0x00ffffff;
8278     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8279     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8280     color = *pos & 0x00ffffff;
8281     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8282
8283     hr = IDirect3DSurface9_UnlockRect(surface);
8284     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8285
8286     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8287      * have full control over the multisampling setting inside this test
8288      */
8289     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8290     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8291     hr = IDirect3DDevice9_BeginScene(device);
8292     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8293     if(SUCCEEDED(hr)) {
8294         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8295         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8296         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8297         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8298         hr = IDirect3DDevice9_EndScene(device);
8299         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8300     }
8301     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8302     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8303
8304     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8305     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8306
8307     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8308     color = *pos & 0x00ffffff;
8309     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8310
8311     hr = IDirect3DSurface9_UnlockRect(surface);
8312     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8313
8314     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8315     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8316     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8317     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8318     IDirect3DPixelShader9_Release(shader);
8319     IDirect3DPixelShader9_Release(shader_frac);
8320     IDirect3DVertexShader9_Release(vshader);
8321     if(surface) IDirect3DSurface9_Release(surface);
8322     IDirect3DSurface9_Release(backbuffer);
8323 }
8324
8325 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8326 {
8327     D3DCOLOR color;
8328
8329     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8330     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8331     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8332     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8333     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8334
8335     ++r;
8336     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8337     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8338     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8339     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8340     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8341
8342     return TRUE;
8343 }
8344
8345 static void pointsize_test(IDirect3DDevice9 *device)
8346 {
8347     HRESULT hr;
8348     D3DCAPS9 caps;
8349     D3DMATRIX matrix;
8350     D3DMATRIX identity;
8351     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8352     DWORD color;
8353     IDirect3DSurface9 *rt, *backbuffer;
8354     IDirect3DTexture9 *tex1, *tex2;
8355     RECT rect = {0, 0, 128, 128};
8356     D3DLOCKED_RECT lr;
8357     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8358                                 0x00000000, 0x00000000};
8359     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8360                                 0x00000000, 0x0000ff00};
8361
8362     const float vertices[] = {
8363         64,     64,     0.1,
8364         128,    64,     0.1,
8365         192,    64,     0.1,
8366         256,    64,     0.1,
8367         320,    64,     0.1,
8368         384,    64,     0.1,
8369         448,    64,     0.1,
8370         512,    64,     0.1,
8371     };
8372
8373     /* 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 */
8374     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;
8375     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;
8376     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;
8377     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;
8378
8379     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;
8380     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;
8381     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;
8382     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;
8383
8384     memset(&caps, 0, sizeof(caps));
8385     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8386     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8387     if(caps.MaxPointSize < 32.0) {
8388         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8389         return;
8390     }
8391
8392     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8393     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8394     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8396     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8397     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8398     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8399     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8400
8401     hr = IDirect3DDevice9_BeginScene(device);
8402     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8403     if (SUCCEEDED(hr))
8404     {
8405         ptsize = 15.0;
8406         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8407         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8410
8411         ptsize = 31.0;
8412         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8413         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8414         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8415         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8416
8417         ptsize = 30.75;
8418         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8419         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8420         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8421         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8422
8423         if (caps.MaxPointSize >= 63.0)
8424         {
8425             ptsize = 63.0;
8426             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8427             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8428             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8429             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8430
8431             ptsize = 62.75;
8432             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8433             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8434             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8435             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8436         }
8437
8438         ptsize = 1.0;
8439         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8440         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8442         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8443
8444         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8445         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8446         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8447         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8448
8449         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8450         ptsize = 15.0;
8451         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8452         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453         ptsize = 1.0;
8454         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8455         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8456         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8457         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8458
8459         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8460         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8461
8462         /* pointsize < pointsize_min < pointsize_max?
8463          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8464         ptsize = 1.0;
8465         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8466         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8467         ptsize = 15.0;
8468         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8469         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8470         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8471         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8472
8473         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8474         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8475
8476         hr = IDirect3DDevice9_EndScene(device);
8477         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8478     }
8479
8480     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8481     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8482     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8483
8484     if (caps.MaxPointSize >= 63.0)
8485     {
8486         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8487         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8488     }
8489
8490     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8491     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8492     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8493     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8494     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8495
8496     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8497
8498     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8499      * generates texture coordinates for the point(result: Yes, it does)
8500      *
8501      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8502      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8503      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8504      */
8505     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8507
8508     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8510     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8511     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8512     memset(&lr, 0, sizeof(lr));
8513     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8514     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8515     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8516     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8517     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8518     memset(&lr, 0, sizeof(lr));
8519     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8520     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8521     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8522     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8523     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8524     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8525     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8526     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8527     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8528     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8529     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8530     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8531     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8532     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8533     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8534     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8535     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8536     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8537     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8538
8539     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8540     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8541     ptsize = 32.0;
8542     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8543     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8544
8545     hr = IDirect3DDevice9_BeginScene(device);
8546     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8547     if(SUCCEEDED(hr))
8548     {
8549         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8550         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8551         hr = IDirect3DDevice9_EndScene(device);
8552         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8553     }
8554
8555     color = getPixelColor(device, 64-4, 64-4);
8556     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8557     color = getPixelColor(device, 64-4, 64+4);
8558     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8559     color = getPixelColor(device, 64+4, 64+4);
8560     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8561     color = getPixelColor(device, 64+4, 64-4);
8562     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8563     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8564
8565     U(matrix).m[0][0] =  1.0f / 64.0f;
8566     U(matrix).m[1][1] = -1.0f / 64.0f;
8567     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8568     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8569
8570     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8571     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8572
8573     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8574             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8575     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8576
8577     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8578     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8579     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8580     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8581
8582     hr = IDirect3DDevice9_BeginScene(device);
8583     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8584     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8585     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8586     hr = IDirect3DDevice9_EndScene(device);
8587     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8588
8589     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8590     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8591     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8592     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8593     IDirect3DSurface9_Release(backbuffer);
8594     IDirect3DSurface9_Release(rt);
8595
8596     color = getPixelColor(device, 64-4, 64-4);
8597     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8598             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8599     color = getPixelColor(device, 64+4, 64-4);
8600     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8601             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8602     color = getPixelColor(device, 64-4, 64+4);
8603     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8604             "Expected color 0x00000000, got 0x%08x.\n", color);
8605     color = getPixelColor(device, 64+4, 64+4);
8606     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8607             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8608
8609     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8610     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8611
8612     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8613     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8614     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8615     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8616     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8617     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8618     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8619     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8620     IDirect3DTexture9_Release(tex1);
8621     IDirect3DTexture9_Release(tex2);
8622
8623     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8624     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8627     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8628     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8629 }
8630
8631 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8632 {
8633     static const DWORD vshader_code[] =
8634     {
8635         0xfffe0300,                                                             /* vs_3_0                     */
8636         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8637         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8638         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8639         0x0000ffff                                                              /* end                        */
8640     };
8641     static const DWORD pshader_code[] =
8642     {
8643         0xffff0300,                                                             /* ps_3_0                     */
8644         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8645         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8646         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8647         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8648         0x0000ffff                                                              /* end                        */
8649     };
8650
8651     HRESULT hr;
8652     IDirect3DVertexShader9 *vs;
8653     IDirect3DPixelShader9 *ps;
8654     IDirect3DTexture9 *tex1, *tex2;
8655     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8656     D3DCAPS9 caps;
8657     DWORD color;
8658     float quad[] = {
8659        -1.0,   -1.0,    0.1,
8660         1.0,   -1.0,    0.1,
8661        -1.0,    1.0,    0.1,
8662         1.0,    1.0,    0.1,
8663     };
8664     float texquad[] = {
8665        -1.0,   -1.0,    0.1,    0.0,    0.0,
8666         0.0,   -1.0,    0.1,    1.0,    0.0,
8667        -1.0,    1.0,    0.1,    0.0,    1.0,
8668         0.0,    1.0,    0.1,    1.0,    1.0,
8669
8670         0.0,   -1.0,    0.1,    0.0,    0.0,
8671         1.0,   -1.0,    0.1,    1.0,    0.0,
8672         0.0,    1.0,    0.1,    0.0,    1.0,
8673         1.0,    1.0,    0.1,    1.0,    1.0,
8674     };
8675
8676     memset(&caps, 0, sizeof(caps));
8677     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8678     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8679     if(caps.NumSimultaneousRTs < 2) {
8680         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8681         return;
8682     }
8683
8684     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8685     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8686
8687     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8688             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8689     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8690
8691     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8692             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8693     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8694     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8695             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8696     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8697     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8698     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8699     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8700     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8701
8702     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8703     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8704     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8705     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8706     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8707     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8708
8709     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8710     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8711     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8712     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8713     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8714     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8715     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8716     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8717     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8718     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8719
8720     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8721     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8722     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8723     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8724     color = getPixelColorFromSurface(readback, 8, 8);
8725     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8726             "Expected color 0x000000ff, got 0x%08x.\n", color);
8727     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8728     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8729     color = getPixelColorFromSurface(readback, 8, 8);
8730     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8731             "Expected color 0x000000ff, got 0x%08x.\n", color);
8732
8733     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8734     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8735     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8736     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8737     color = getPixelColorFromSurface(readback, 8, 8);
8738     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8739             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8740     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8741     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8742     color = getPixelColorFromSurface(readback, 8, 8);
8743     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8744             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8745
8746     hr = IDirect3DDevice9_BeginScene(device);
8747     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8748     if(SUCCEEDED(hr)) {
8749         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8750         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8751
8752         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8753         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8754         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8755         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8756         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8757         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8758         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8759         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8760         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8761         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8762
8763         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8764         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8766         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8767
8768         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8769         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8771         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8772
8773         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8774         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8775
8776         hr = IDirect3DDevice9_EndScene(device);
8777         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8778     }
8779
8780     color = getPixelColor(device, 160, 240);
8781     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8782     color = getPixelColor(device, 480, 240);
8783     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8784     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8785
8786     IDirect3DPixelShader9_Release(ps);
8787     IDirect3DVertexShader9_Release(vs);
8788     IDirect3DTexture9_Release(tex1);
8789     IDirect3DTexture9_Release(tex2);
8790     IDirect3DSurface9_Release(surf1);
8791     IDirect3DSurface9_Release(surf2);
8792     IDirect3DSurface9_Release(backbuf);
8793     IDirect3DSurface9_Release(readback);
8794 }
8795
8796 struct formats {
8797     const char *fmtName;
8798     D3DFORMAT textureFormat;
8799     DWORD resultColorBlending;
8800     DWORD resultColorNoBlending;
8801 };
8802
8803 const struct formats test_formats[] = {
8804   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8805   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8806   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8807   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8808   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8809   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8810   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8811   { NULL, 0 }
8812 };
8813
8814 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8815 {
8816     HRESULT hr;
8817     IDirect3DTexture9 *offscreenTexture = NULL;
8818     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8819     IDirect3D9 *d3d = NULL;
8820     DWORD color;
8821     DWORD r0, g0, b0, r1, g1, b1;
8822     int fmt_index;
8823
8824     static const float quad[][5] = {
8825         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8826         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8827         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8828         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8829     };
8830
8831     /* Quad with R=0x10, G=0x20 */
8832     static const struct vertex quad1[] = {
8833         {-1.0f, -1.0f, 0.1f, 0x80102000},
8834         {-1.0f,  1.0f, 0.1f, 0x80102000},
8835         { 1.0f, -1.0f, 0.1f, 0x80102000},
8836         { 1.0f,  1.0f, 0.1f, 0x80102000},
8837     };
8838
8839     /* Quad with R=0x20, G=0x10 */
8840     static const struct vertex quad2[] = {
8841         {-1.0f, -1.0f, 0.1f, 0x80201000},
8842         {-1.0f,  1.0f, 0.1f, 0x80201000},
8843         { 1.0f, -1.0f, 0.1f, 0x80201000},
8844         { 1.0f,  1.0f, 0.1f, 0x80201000},
8845     };
8846
8847     IDirect3DDevice9_GetDirect3D(device, &d3d);
8848
8849     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8850     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8851     if(!backbuffer) {
8852         goto out;
8853     }
8854
8855     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8856     {
8857         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8858         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8859            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8860            continue;
8861         }
8862
8863         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8864         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8865
8866         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8867         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8868         if(!offscreenTexture) {
8869             continue;
8870         }
8871
8872         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8873         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8874         if(!offscreen) {
8875             continue;
8876         }
8877
8878         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8879         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8880
8881         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8882         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8883         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8884         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8885         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8886         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8887         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8888         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8889         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8890         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8891
8892         /* Below we will draw two quads with different colors and try to blend them together.
8893          * The result color is compared with the expected outcome.
8894          */
8895         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8896             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8897             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8898             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8899             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8900
8901             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8902             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8903
8904             /* Draw a quad using color 0x0010200 */
8905             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8906             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8907             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8908             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8909             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8910             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8911
8912             /* Draw a quad using color 0x0020100 */
8913             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8914             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8915             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8916             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8917             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8918             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8919
8920             /* We don't want to blend the result on the backbuffer */
8921             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8922             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8923
8924             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8925             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8926             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8927             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8928             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8929
8930             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8931             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8932
8933             /* This time with the texture */
8934             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8935             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8936
8937             IDirect3DDevice9_EndScene(device);
8938         }
8939
8940         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8941             /* Compare the color of the center quad with our expectation */
8942             color = getPixelColor(device, 320, 240);
8943             r0 = (color & 0x00ff0000) >> 16;
8944             g0 = (color & 0x0000ff00) >>  8;
8945             b0 = (color & 0x000000ff) >>  0;
8946
8947             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8948             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8949             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8950
8951             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8952                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8953                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8954                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8955         } else {
8956             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8957              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8958              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8959             color = getPixelColor(device, 320, 240);
8960             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);
8961         }
8962         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8963
8964         IDirect3DDevice9_SetTexture(device, 0, NULL);
8965         if(offscreenTexture) {
8966             IDirect3DTexture9_Release(offscreenTexture);
8967         }
8968         if(offscreen) {
8969             IDirect3DSurface9_Release(offscreen);
8970         }
8971     }
8972
8973 out:
8974     /* restore things */
8975     if(backbuffer) {
8976         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8977         IDirect3DSurface9_Release(backbuffer);
8978     }
8979 }
8980
8981 static void tssargtemp_test(IDirect3DDevice9 *device)
8982 {
8983     HRESULT hr;
8984     DWORD color;
8985     static const struct vertex quad[] = {
8986         {-1.0,     -1.0,    0.1,    0x00ff0000},
8987         { 1.0,     -1.0,    0.1,    0x00ff0000},
8988         {-1.0,      1.0,    0.1,    0x00ff0000},
8989         { 1.0,      1.0,    0.1,    0x00ff0000}
8990     };
8991     D3DCAPS9 caps;
8992
8993     memset(&caps, 0, sizeof(caps));
8994     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8995     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8996     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8997         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8998         return;
8999     }
9000
9001     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9002     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9003
9004     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9005     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9006     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9007     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9008
9009     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9010     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9011     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9012     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9013     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9014     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9015
9016     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9017     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9018     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9019     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9020     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9021     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9022
9023     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9024     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9025
9026     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9027     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9028     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9029     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9030
9031     hr = IDirect3DDevice9_BeginScene(device);
9032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9033     if(SUCCEEDED(hr)) {
9034         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9035         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9036         hr = IDirect3DDevice9_EndScene(device);
9037         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9038     }
9039     color = getPixelColor(device, 320, 240);
9040     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9041     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9042
9043     /* Set stage 1 back to default */
9044     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9045     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9046     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9047     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9048     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9049     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9050     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9051     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9052     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9053     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9054 }
9055
9056 struct testdata
9057 {
9058     DWORD idxVertex; /* number of instances in the first stream */
9059     DWORD idxColor; /* number of instances in the second stream */
9060     DWORD idxInstance; /* should be 1 ?? */
9061     DWORD color1; /* color 1 instance */
9062     DWORD color2; /* color 2 instance */
9063     DWORD color3; /* color 3 instance */
9064     DWORD color4; /* color 4 instance */
9065     WORD strVertex; /* specify which stream to use 0-2*/
9066     WORD strColor;
9067     WORD strInstance;
9068 };
9069
9070 static const struct testdata testcases[]=
9071 {
9072     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9073     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9074     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9075     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9076     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9077     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9078     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9079     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9080     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9081     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9082     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9083     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9084     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9085     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9086     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9087 /*
9088     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9089     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9090 */
9091 };
9092
9093 /* Drawing Indexed Geometry with instances*/
9094 static void stream_test(IDirect3DDevice9 *device)
9095 {
9096     IDirect3DVertexBuffer9 *vb = NULL;
9097     IDirect3DVertexBuffer9 *vb2 = NULL;
9098     IDirect3DVertexBuffer9 *vb3 = NULL;
9099     IDirect3DIndexBuffer9 *ib = NULL;
9100     IDirect3DVertexDeclaration9 *pDecl = NULL;
9101     IDirect3DVertexShader9 *shader = NULL;
9102     HRESULT hr;
9103     BYTE *data;
9104     DWORD color;
9105     DWORD ind;
9106     unsigned i;
9107
9108     const DWORD shader_code[] =
9109     {
9110         0xfffe0101,                                     /* vs_1_1 */
9111         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9112         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9113         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9114         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9115         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9116         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9117         0x0000ffff
9118     };
9119
9120     const float quad[][3] =
9121     {
9122         {-0.5f, -0.5f,  1.1f}, /*0 */
9123         {-0.5f,  0.5f,  1.1f}, /*1 */
9124         { 0.5f, -0.5f,  1.1f}, /*2 */
9125         { 0.5f,  0.5f,  1.1f}, /*3 */
9126     };
9127
9128     const float vertcolor[][4] =
9129     {
9130         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9131         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9132         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9133         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9134     };
9135
9136     /* 4 position for 4 instances */
9137     const float instancepos[][3] =
9138     {
9139         {-0.6f,-0.6f, 0.0f},
9140         { 0.6f,-0.6f, 0.0f},
9141         { 0.6f, 0.6f, 0.0f},
9142         {-0.6f, 0.6f, 0.0f},
9143     };
9144
9145     short indices[] = {0, 1, 2, 1, 2, 3};
9146
9147     D3DVERTEXELEMENT9 decl[] =
9148     {
9149         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9150         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9151         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9152         D3DDECL_END()
9153     };
9154
9155     /* set the default value because it isn't done in wine? */
9156     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9157     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9158
9159     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9160     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9161     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9162
9163     /* check wrong cases */
9164     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9165     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9166     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9167     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9168     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9169     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9170     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9171     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9172     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9173     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9174     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9175     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9176     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9177     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9178     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9179     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9180     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9181     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9182     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9183     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9184
9185     /* set the default value back */
9186     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9187     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9188
9189     /* create all VertexBuffers*/
9190     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9191     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9192     if(!vb) {
9193         skip("Failed to create a vertex buffer\n");
9194         return;
9195     }
9196     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9197     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9198     if(!vb2) {
9199         skip("Failed to create a vertex buffer\n");
9200         goto out;
9201     }
9202     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9203     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9204     if(!vb3) {
9205         skip("Failed to create a vertex buffer\n");
9206         goto out;
9207     }
9208
9209     /* create IndexBuffer*/
9210     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9211     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9212     if(!ib) {
9213         skip("Failed to create a index buffer\n");
9214         goto out;
9215     }
9216
9217     /* copy all Buffers (Vertex + Index)*/
9218     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9219     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9220     memcpy(data, quad, sizeof(quad));
9221     hr = IDirect3DVertexBuffer9_Unlock(vb);
9222     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9223     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9224     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9225     memcpy(data, vertcolor, sizeof(vertcolor));
9226     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9227     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9228     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9229     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9230     memcpy(data, instancepos, sizeof(instancepos));
9231     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9232     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9233     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9234     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9235     memcpy(data, indices, sizeof(indices));
9236     hr = IDirect3DIndexBuffer9_Unlock(ib);
9237     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9238
9239     /* create VertexShader */
9240     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9241     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9242     if(!shader) {
9243         skip("Failed to create a vetex shader\n");
9244         goto out;
9245     }
9246
9247     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9248     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9249
9250     hr = IDirect3DDevice9_SetIndices(device, ib);
9251     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9252
9253     /* run all tests */
9254     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9255     {
9256         struct testdata act = testcases[i];
9257         decl[0].Stream = act.strVertex;
9258         decl[1].Stream = act.strColor;
9259         decl[2].Stream = act.strInstance;
9260         /* create VertexDeclarations */
9261         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9262         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9263
9264         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9265         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9266
9267         hr = IDirect3DDevice9_BeginScene(device);
9268         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9269         if(SUCCEEDED(hr))
9270         {
9271             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9272             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9273
9274             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9275             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9276             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9277             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9278
9279             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9280             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9281             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9282             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9283
9284             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9285             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9286             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9287             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9288
9289             /* don't know if this is right (1*3 and 4*1)*/
9290             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9291             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9292             hr = IDirect3DDevice9_EndScene(device);
9293             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9294
9295             /* set all StreamSource && StreamSourceFreq back to default */
9296             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9297             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9298             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9299             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9300             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9301             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9302             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9303             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9304             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9305             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9306             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9307             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9308         }
9309
9310         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9311         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9312
9313         color = getPixelColor(device, 160, 360);
9314         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9315         color = getPixelColor(device, 480, 360);
9316         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9317         color = getPixelColor(device, 480, 120);
9318         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9319         color = getPixelColor(device, 160, 120);
9320         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9321
9322         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9323         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9324     }
9325
9326     hr = IDirect3DDevice9_SetIndices(device, NULL);
9327     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9328
9329 out:
9330     if(vb) IDirect3DVertexBuffer9_Release(vb);
9331     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9332     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9333     if(ib)IDirect3DIndexBuffer9_Release(ib);
9334     if(shader)IDirect3DVertexShader9_Release(shader);
9335 }
9336
9337 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9338     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9339     IDirect3DTexture9 *dsttex = NULL;
9340     HRESULT hr;
9341     DWORD color;
9342     D3DRECT r1 = {0,  0,  50,  50 };
9343     D3DRECT r2 = {50, 0,  100, 50 };
9344     D3DRECT r3 = {50, 50, 100, 100};
9345     D3DRECT r4 = {0,  50,  50, 100};
9346     const float quad[] = {
9347         -1.0,   -1.0,   0.1,    0.0,    0.0,
9348          1.0,   -1.0,   0.1,    1.0,    0.0,
9349         -1.0,    1.0,   0.1,    0.0,    1.0,
9350          1.0,    1.0,   0.1,    1.0,    1.0,
9351     };
9352
9353     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9354     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9355
9356     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9357     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9358     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9359     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9360
9361     if(!src || !dsttex) {
9362         skip("One or more test resources could not be created\n");
9363         goto cleanup;
9364     }
9365
9366     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9367     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9368
9369     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9370     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9371
9372     /* Clear the StretchRect destination for debugging */
9373     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9374     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9375     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9376     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9377
9378     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9379     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9380
9381     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9382     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9383     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9384     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9385     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9386     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9387     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9388     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9389
9390     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9391      * the target -> texture GL blit path
9392      */
9393     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9394     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9395     IDirect3DSurface9_Release(dst);
9396
9397     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9398     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9399
9400     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9401     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9402     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9403     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9404     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9405     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9406     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9407     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9408
9409     hr = IDirect3DDevice9_BeginScene(device);
9410     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9411     if(SUCCEEDED(hr)) {
9412         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9413         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9414         hr = IDirect3DDevice9_EndScene(device);
9415         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9416     }
9417
9418     color = getPixelColor(device, 160, 360);
9419     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9420     color = getPixelColor(device, 480, 360);
9421     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9422     color = getPixelColor(device, 480, 120);
9423     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9424     color = getPixelColor(device, 160, 120);
9425     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9426     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9428
9429     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9430     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9431     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9432     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9433
9434 cleanup:
9435     if(src) IDirect3DSurface9_Release(src);
9436     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9437     if(dsttex) IDirect3DTexture9_Release(dsttex);
9438 }
9439
9440 static void texop_test(IDirect3DDevice9 *device)
9441 {
9442     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9443     IDirect3DTexture9 *texture = NULL;
9444     D3DLOCKED_RECT locked_rect;
9445     D3DCOLOR color;
9446     D3DCAPS9 caps;
9447     HRESULT hr;
9448     unsigned i;
9449
9450     static const struct {
9451         float x, y, z;
9452         float s, t;
9453         D3DCOLOR diffuse;
9454     } quad[] = {
9455         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9456         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9457         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9458         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9459     };
9460
9461     static const D3DVERTEXELEMENT9 decl_elements[] = {
9462         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9463         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9464         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9465         D3DDECL_END()
9466     };
9467
9468     static const struct {
9469         D3DTEXTUREOP op;
9470         const char *name;
9471         DWORD caps_flag;
9472         D3DCOLOR result;
9473     } test_data[] = {
9474         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9475         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9476         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9477         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9478         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9479         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9480         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9481         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9482         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9483         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9484         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9485         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9486         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9487         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9488         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9489         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9490         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9491         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9492         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9493         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9494         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9495         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9496         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9497     };
9498
9499     memset(&caps, 0, sizeof(caps));
9500     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9501     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9502
9503     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9504     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9505     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9506     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9507
9508     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9509     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9510     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9511     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9512     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9513     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9514     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9515     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9516     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9517
9518     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9519     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9520     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9521     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9522     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9523     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9524
9525     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9526     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9527
9528     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9529     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9530     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9531     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9532     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9533     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9534
9535     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9536     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9537
9538     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9539     {
9540         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9541         {
9542             skip("tex operation %s not supported\n", test_data[i].name);
9543             continue;
9544         }
9545
9546         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9547         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9548
9549         hr = IDirect3DDevice9_BeginScene(device);
9550         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9551
9552         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9553         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9554
9555         hr = IDirect3DDevice9_EndScene(device);
9556         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9557
9558         color = getPixelColor(device, 320, 240);
9559         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9560                 test_data[i].name, color, test_data[i].result);
9561
9562         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9563         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9564     }
9565
9566     if (texture) IDirect3DTexture9_Release(texture);
9567     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9568 }
9569
9570 static void yuv_color_test(IDirect3DDevice9 *device) {
9571     HRESULT hr;
9572     IDirect3DSurface9 *surface = NULL, *target = NULL;
9573     unsigned int fmt, i;
9574     D3DFORMAT format;
9575     const char *fmt_string;
9576     D3DLOCKED_RECT lr;
9577     IDirect3D9 *d3d;
9578     HRESULT color;
9579     DWORD ref_color_left, ref_color_right;
9580
9581     struct {
9582         DWORD in;           /* The input color */
9583         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9584         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9585         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9586         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9587     } test_data[] = {
9588     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9589      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9590      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9591      * that
9592      */
9593       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9594       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9595       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9596       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9597       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9598       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9599       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9600       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9601       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9602       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9603       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9604       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9605       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9606       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9607
9608       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9609       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9610       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9611       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9612     };
9613
9614     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9615     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9616     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9617     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9618
9619     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9620     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9621
9622     for(fmt = 0; fmt < 2; fmt++) {
9623         if(fmt == 0) {
9624             format = D3DFMT_UYVY;
9625             fmt_string = "D3DFMT_UYVY";
9626         } else {
9627             format = D3DFMT_YUY2;
9628             fmt_string = "D3DFMT_YUY2";
9629         }
9630
9631         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9632                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9633                        */
9634         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9635                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9636             skip("%s is not supported\n", fmt_string);
9637             continue;
9638         }
9639
9640         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9641         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9642         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9643
9644         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9645             if(fmt == 0) {
9646                 ref_color_left = test_data[i].uyvy_left;
9647                 ref_color_right = test_data[i].uyvy_right;
9648             } else {
9649                 ref_color_left = test_data[i].yuy2_left;
9650                 ref_color_right = test_data[i].yuy2_right;
9651             }
9652
9653             memset(&lr, 0, sizeof(lr));
9654             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9655             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9656             *((DWORD *) lr.pBits) = test_data[i].in;
9657             hr = IDirect3DSurface9_UnlockRect(surface);
9658             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9659
9660             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9661             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9662             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9663             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9664
9665             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9666              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9667              * want to add tests for the filtered pixels as well.
9668              *
9669              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9670              * differently, so we need a max diff of 16
9671              */
9672             color = getPixelColor(device, 40, 240);
9673             ok(color_match(color, ref_color_left, 18),
9674                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9675                test_data[i].in, color, ref_color_left, fmt_string);
9676             color = getPixelColor(device, 600, 240);
9677             ok(color_match(color, ref_color_right, 18),
9678                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9679                test_data[i].in, color, ref_color_right, fmt_string);
9680             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9681             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9682         }
9683         IDirect3DSurface9_Release(surface);
9684     }
9685     IDirect3DSurface9_Release(target);
9686     IDirect3D9_Release(d3d);
9687 }
9688
9689 static void texop_range_test(IDirect3DDevice9 *device)
9690 {
9691     static const struct {
9692         float x, y, z;
9693         D3DCOLOR diffuse;
9694     } quad[] = {
9695         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9696         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9697         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9698         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9699     };
9700     HRESULT hr;
9701     IDirect3DTexture9 *texture;
9702     D3DLOCKED_RECT locked_rect;
9703     D3DCAPS9 caps;
9704     DWORD color;
9705
9706     /* We need ADD and SUBTRACT operations */
9707     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9708     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9709     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9710         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9711         return;
9712     }
9713     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9714         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9715         return;
9716     }
9717
9718     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9719     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9720     /* Stage 1: result = diffuse(=1.0) + diffuse
9721      * stage 2: result = result - tfactor(= 0.5)
9722      */
9723     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9724     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9725     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9726     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9727     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9728     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9729     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9730     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9731     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9732     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9733     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9734     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9735     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9736     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9737
9738     hr = IDirect3DDevice9_BeginScene(device);
9739     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9740     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9741     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9742     hr = IDirect3DDevice9_EndScene(device);
9743     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9744
9745     color = getPixelColor(device, 320, 240);
9746     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9747        color);
9748     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9749     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9750
9751     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9752     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9753     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9754     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9755     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9756     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9757     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9758     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9759     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9760
9761     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9762      * stage 2: result = result + diffuse(1.0)
9763      */
9764     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9765     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9766     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9767     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9768     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9769     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9770     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9771     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9772     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9773     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9774     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9775     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9776     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9777     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9778
9779     hr = IDirect3DDevice9_BeginScene(device);
9780     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9781     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9782     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9783     hr = IDirect3DDevice9_EndScene(device);
9784     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9785
9786     color = getPixelColor(device, 320, 240);
9787     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9788        color);
9789     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9790     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9791
9792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9793     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9794     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9795     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9796     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9797     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9798     IDirect3DTexture9_Release(texture);
9799 }
9800
9801 static void alphareplicate_test(IDirect3DDevice9 *device) {
9802     struct vertex quad[] = {
9803         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9804         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9805         { -1.0,     1.0,    0.1,    0x80ff00ff },
9806         {  1.0,     1.0,    0.1,    0x80ff00ff },
9807     };
9808     HRESULT hr;
9809     DWORD color;
9810
9811     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9812     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9813
9814     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9815     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9816
9817     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9818     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9819     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9820     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9821
9822     hr = IDirect3DDevice9_BeginScene(device);
9823     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9824     if(SUCCEEDED(hr)) {
9825         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9826         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9827         hr = IDirect3DDevice9_EndScene(device);
9828         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9829     }
9830
9831     color = getPixelColor(device, 320, 240);
9832     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9833        color);
9834     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9835     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9836
9837     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9838     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9839
9840 }
9841
9842 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9843     HRESULT hr;
9844     D3DCAPS9 caps;
9845     DWORD color;
9846     struct vertex quad[] = {
9847         { -1.0,    -1.0,    0.1,    0x408080c0 },
9848         {  1.0,    -1.0,    0.1,    0x408080c0 },
9849         { -1.0,     1.0,    0.1,    0x408080c0 },
9850         {  1.0,     1.0,    0.1,    0x408080c0 },
9851     };
9852
9853     memset(&caps, 0, sizeof(caps));
9854     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9855     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9856     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9857         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9858         return;
9859     }
9860
9861     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9862     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9863
9864     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9865     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9866
9867     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9868      * mov r0.a, diffuse.a
9869      * mov r0, r0.a
9870      *
9871      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9872      * 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
9873      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9874      */
9875     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9876     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9877     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9878     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9879     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9880     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9881     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9882     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9883     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9884     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9885     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9886     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9887     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9888     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9889     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9890     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9891     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9892     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9893
9894     hr = IDirect3DDevice9_BeginScene(device);
9895     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9896     if(SUCCEEDED(hr)) {
9897         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9898         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9899         hr = IDirect3DDevice9_EndScene(device);
9900         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9901     }
9902
9903     color = getPixelColor(device, 320, 240);
9904     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9905        color);
9906     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9907     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9908
9909     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9910     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9911     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9912     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9913     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9914     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9915 }
9916
9917 static void zwriteenable_test(IDirect3DDevice9 *device) {
9918     HRESULT hr;
9919     DWORD color;
9920     struct vertex quad1[] = {
9921         { -1.0,  -1.0,  0.1,    0x00ff0000},
9922         { -1.0,   1.0,  0.1,    0x00ff0000},
9923         {  1.0,  -1.0,  0.1,    0x00ff0000},
9924         {  1.0,   1.0,  0.1,    0x00ff0000},
9925     };
9926     struct vertex quad2[] = {
9927         { -1.0,  -1.0,  0.9,    0x0000ff00},
9928         { -1.0,   1.0,  0.9,    0x0000ff00},
9929         {  1.0,  -1.0,  0.9,    0x0000ff00},
9930         {  1.0,   1.0,  0.9,    0x0000ff00},
9931     };
9932
9933     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9934     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9935
9936     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9937     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9938     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9939     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9940     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9941     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9942     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9944
9945     hr = IDirect3DDevice9_BeginScene(device);
9946     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9947     if(SUCCEEDED(hr)) {
9948         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9949          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9950          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9951          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9952          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9953          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9954          */
9955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9956         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9957         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9958         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9959         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9960         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9961
9962         hr = IDirect3DDevice9_EndScene(device);
9963         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9964     }
9965
9966     color = getPixelColor(device, 320, 240);
9967     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9968        color);
9969     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9970     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9971
9972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9973     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9974 }
9975
9976 static void alphatest_test(IDirect3DDevice9 *device) {
9977 #define ALPHATEST_PASSED 0x0000ff00
9978 #define ALPHATEST_FAILED 0x00ff0000
9979     struct {
9980         D3DCMPFUNC  func;
9981         DWORD       color_less;
9982         DWORD       color_equal;
9983         DWORD       color_greater;
9984     } testdata[] = {
9985         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
9986         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
9987         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
9988         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
9989         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
9990         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
9991         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
9992         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
9993     };
9994     unsigned int i, j;
9995     HRESULT hr;
9996     DWORD color;
9997     struct vertex quad[] = {
9998         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
9999         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10000         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10001         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10002     };
10003     D3DCAPS9 caps;
10004
10005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10006     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10007     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10008     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10009
10010     for(j = 0; j < 2; j++) {
10011         if(j == 1) {
10012             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10013              * the alpha test either for performance reasons(floating point RTs) or to work
10014              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10015              * codepath for ffp and shader in this case, and the test should cover both
10016              */
10017             IDirect3DPixelShader9 *ps;
10018             DWORD shader_code[] = {
10019                 0xffff0101,                                 /* ps_1_1           */
10020                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10021                 0x0000ffff                                  /* end              */
10022             };
10023             memset(&caps, 0, sizeof(caps));
10024             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10025             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10026             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10027                 break;
10028             }
10029
10030             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10031             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10032             IDirect3DDevice9_SetPixelShader(device, ps);
10033             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10034             IDirect3DPixelShader9_Release(ps);
10035         }
10036
10037         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10038             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10039             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10040
10041             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10042             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10043             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10044             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10045             hr = IDirect3DDevice9_BeginScene(device);
10046             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10047             if(SUCCEEDED(hr)) {
10048                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10049                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10050                 hr = IDirect3DDevice9_EndScene(device);
10051                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10052             }
10053             color = getPixelColor(device, 320, 240);
10054             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10055             color, testdata[i].color_less, testdata[i].func);
10056             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10057             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10058
10059             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10060             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10061             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10062             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10063             hr = IDirect3DDevice9_BeginScene(device);
10064             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10065             if(SUCCEEDED(hr)) {
10066                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10067                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10068                 hr = IDirect3DDevice9_EndScene(device);
10069                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10070             }
10071             color = getPixelColor(device, 320, 240);
10072             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10073             color, testdata[i].color_equal, testdata[i].func);
10074             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10075             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10076
10077             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10078             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10079             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10080             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10081             hr = IDirect3DDevice9_BeginScene(device);
10082             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10083             if(SUCCEEDED(hr)) {
10084                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10085                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10086                 hr = IDirect3DDevice9_EndScene(device);
10087                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10088             }
10089             color = getPixelColor(device, 320, 240);
10090             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10091             color, testdata[i].color_greater, testdata[i].func);
10092             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10093             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10094         }
10095     }
10096
10097     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10098     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10099     IDirect3DDevice9_SetPixelShader(device, NULL);
10100     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10101 }
10102
10103 static void sincos_test(IDirect3DDevice9 *device) {
10104     const DWORD sin_shader_code[] = {
10105         0xfffe0200,                                                                 /* vs_2_0                       */
10106         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10107         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10108         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10109         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10110         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10111         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10112         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10113         0x0000ffff                                                                  /* end                          */
10114     };
10115     const DWORD cos_shader_code[] = {
10116         0xfffe0200,                                                                 /* vs_2_0                       */
10117         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10118         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10119         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10120         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10121         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10122         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10123         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10124         0x0000ffff                                                                  /* end                          */
10125     };
10126     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10127     HRESULT hr;
10128     struct {
10129         float x, y, z;
10130     } data[1280];
10131     unsigned int i;
10132     float sincosc1[4] = {D3DSINCOSCONST1};
10133     float sincosc2[4] = {D3DSINCOSCONST2};
10134
10135     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10136     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10137
10138     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10139     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10140     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10141     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10142     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10143     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10144     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10145     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10146     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10147     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10148
10149     /* Generate a point from -1 to 1 every 0.5 pixels */
10150     for(i = 0; i < 1280; i++) {
10151         data[i].x = (-640.0 + i) / 640.0;
10152         data[i].y = 0.0;
10153         data[i].z = 0.1;
10154     }
10155
10156     hr = IDirect3DDevice9_BeginScene(device);
10157     if(SUCCEEDED(hr)) {
10158         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10159         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10160         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10161         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10162
10163         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10164         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10166         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10167
10168         hr = IDirect3DDevice9_EndScene(device);
10169         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10170     }
10171     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10172     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10173     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10174
10175     IDirect3DDevice9_SetVertexShader(device, NULL);
10176     IDirect3DVertexShader9_Release(sin_shader);
10177     IDirect3DVertexShader9_Release(cos_shader);
10178 }
10179
10180 static void loop_index_test(IDirect3DDevice9 *device) {
10181     const DWORD shader_code[] = {
10182         0xfffe0200,                                                 /* vs_2_0                   */
10183         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10184         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10185         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10186         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10187         0x0000001d,                                                 /* endloop                  */
10188         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10189         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10190         0x0000ffff                                                  /* END                      */
10191     };
10192     IDirect3DVertexShader9 *shader;
10193     HRESULT hr;
10194     DWORD color;
10195     const float quad[] = {
10196         -1.0,   -1.0,   0.1,
10197          1.0,   -1.0,   0.1,
10198         -1.0,    1.0,   0.1,
10199          1.0,    1.0,   0.1
10200     };
10201     const float zero[4] = {0, 0, 0, 0};
10202     const float one[4] = {1, 1, 1, 1};
10203     int i0[4] = {2, 10, -3, 0};
10204     float values[4];
10205
10206     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10207     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10208     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10209     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10210     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10211     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10212     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10213     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10214
10215     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10216     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10217     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10218     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10219     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10220     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10221     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10222     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10223     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10224     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10225     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10226     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10227     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10228     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10229     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10230     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10231     values[0] = 1.0;
10232     values[1] = 1.0;
10233     values[2] = 0.0;
10234     values[3] = 0.0;
10235     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10236     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10237     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10238     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10239     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10240     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10241     values[0] = -1.0;
10242     values[1] = 0.0;
10243     values[2] = 0.0;
10244     values[3] = 0.0;
10245     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10246     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10247     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10248     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10249     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10250     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10251     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10252     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10253     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10254     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10255
10256     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10257     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10258
10259     hr = IDirect3DDevice9_BeginScene(device);
10260     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10261     if(SUCCEEDED(hr))
10262     {
10263         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10264         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10265         hr = IDirect3DDevice9_EndScene(device);
10266         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10267     }
10268     color = getPixelColor(device, 320, 240);
10269     ok(color_match(color, 0x0000ff00, 1),
10270        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10271     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10272     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10273
10274     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10275     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10276     IDirect3DVertexShader9_Release(shader);
10277 }
10278
10279 static void sgn_test(IDirect3DDevice9 *device) {
10280     const DWORD shader_code[] = {
10281         0xfffe0200,                                                             /* vs_2_0                       */
10282         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10283         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10284         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10285         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10286         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10287         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10288         0x0000ffff                                                              /* end                          */
10289     };
10290     IDirect3DVertexShader9 *shader;
10291     HRESULT hr;
10292     DWORD color;
10293     const float quad[] = {
10294         -1.0,   -1.0,   0.1,
10295          1.0,   -1.0,   0.1,
10296         -1.0,    1.0,   0.1,
10297          1.0,    1.0,   0.1
10298     };
10299
10300     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10302     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10303     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10304     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10305     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10306     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10307     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10308
10309     hr = IDirect3DDevice9_BeginScene(device);
10310     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10311     if(SUCCEEDED(hr))
10312     {
10313         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10314         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10315         hr = IDirect3DDevice9_EndScene(device);
10316         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10317     }
10318     color = getPixelColor(device, 320, 240);
10319     ok(color_match(color, 0x008000ff, 1),
10320        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10321     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10322     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10323
10324     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10325     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10326     IDirect3DVertexShader9_Release(shader);
10327 }
10328
10329 static void viewport_test(IDirect3DDevice9 *device) {
10330     HRESULT hr;
10331     DWORD color;
10332     D3DVIEWPORT9 vp, old_vp;
10333     BOOL draw_failed = TRUE;
10334     const float quad[] =
10335     {
10336         -0.5,   -0.5,   0.1,
10337          0.5,   -0.5,   0.1,
10338         -0.5,    0.5,   0.1,
10339          0.5,    0.5,   0.1
10340     };
10341
10342     memset(&old_vp, 0, sizeof(old_vp));
10343     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10344     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10345
10346     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10347     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10348
10349     /* Test a viewport with Width and Height bigger than the surface dimensions
10350      *
10351      * TODO: Test Width < surface.width, but X + Width > surface.width
10352      * TODO: Test Width < surface.width, what happens with the height?
10353      *
10354      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10355      * and Height fields bigger than the framebuffer. However, it later refuses
10356      * to draw.
10357      */
10358     memset(&vp, 0, sizeof(vp));
10359     vp.X = 0;
10360     vp.Y = 0;
10361     vp.Width = 10000;
10362     vp.Height = 10000;
10363     vp.MinZ = 0.0;
10364     vp.MaxZ = 0.0;
10365     hr = IDirect3DDevice9_SetViewport(device, &vp);
10366     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10367
10368     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10369     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10370     hr = IDirect3DDevice9_BeginScene(device);
10371     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10372     if(SUCCEEDED(hr))
10373     {
10374         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10375         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10376         draw_failed = FAILED(hr);
10377         hr = IDirect3DDevice9_EndScene(device);
10378         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10379     }
10380
10381     if(!draw_failed)
10382     {
10383         color = getPixelColor(device, 158, 118);
10384         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10385         color = getPixelColor(device, 162, 118);
10386         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10387         color = getPixelColor(device, 158, 122);
10388         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10389         color = getPixelColor(device, 162, 122);
10390         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10391
10392         color = getPixelColor(device, 478, 358);
10393         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10394         color = getPixelColor(device, 482, 358);
10395         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10396         color = getPixelColor(device, 478, 362);
10397         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10398         color = getPixelColor(device, 482, 362);
10399         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10400     }
10401
10402     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10403     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10404
10405     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10406     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10407 }
10408
10409 /* This test tests depth clamping / clipping behaviour:
10410  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10411  *   minimum/maximum z value.
10412  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10413  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10414  *   - Pretransformed vertices behave the same as regular vertices.
10415  */
10416 static void depth_clamp_test(IDirect3DDevice9 *device)
10417 {
10418     const struct tvertex quad1[] =
10419     {
10420         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10421         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10422         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10423         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10424     };
10425     const struct tvertex quad2[] =
10426     {
10427         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10428         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10429         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10430         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10431     };
10432     const struct vertex quad3[] =
10433     {
10434         {-0.65, 0.55,  5.0f,      0xffffffff},
10435         {-0.35, 0.55,  5.0f,      0xffffffff},
10436         {-0.65, 0.15,  5.0f,      0xffffffff},
10437         {-0.35, 0.15,  5.0f,      0xffffffff},
10438     };
10439     const struct vertex quad4[] =
10440     {
10441         {-0.87, 0.83, 10.0f,      0xffffffff},
10442         {-0.65, 0.83, 10.0f,      0xffffffff},
10443         {-0.87, 0.55, 10.0f,      0xffffffff},
10444         {-0.65, 0.55, 10.0f,      0xffffffff},
10445     };
10446     const struct vertex quad5[] =
10447     {
10448         { -0.5,  0.5, 10.0f,      0xff14f914},
10449         {  0.5,  0.5, 10.0f,      0xff14f914},
10450         { -0.5, -0.5, 10.0f,      0xff14f914},
10451         {  0.5, -0.5, 10.0f,      0xff14f914},
10452     };
10453     const struct tvertex quad6[] =
10454     {
10455         {    0,  120, 10.0f, 1.0, 0xfff91414},
10456         {  640,  120, 10.0f, 1.0, 0xfff91414},
10457         {    0,  180, 10.0f, 1.0, 0xfff91414},
10458         {  640,  180, 10.0f, 1.0, 0xfff91414},
10459     };
10460
10461     D3DVIEWPORT9 vp;
10462     D3DCOLOR color;
10463     HRESULT hr;
10464
10465     vp.X = 0;
10466     vp.Y = 0;
10467     vp.Width = 640;
10468     vp.Height = 480;
10469     vp.MinZ = 0.0;
10470     vp.MaxZ = 7.5;
10471
10472     hr = IDirect3DDevice9_SetViewport(device, &vp);
10473     if(FAILED(hr))
10474     {
10475         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10476          * the tests because the 7.5 is just intended to show that it doesn't have
10477          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10478          * viewport and continue.
10479          */
10480         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10481         vp.MaxZ = 1.0;
10482         hr = IDirect3DDevice9_SetViewport(device, &vp);
10483     }
10484     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10485
10486     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10487     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10488
10489     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10490     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10491     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10492     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10493     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10494     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10495     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10496     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10497
10498     hr = IDirect3DDevice9_BeginScene(device);
10499     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10500
10501     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10502     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10503
10504     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10505     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10506     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10507     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10508
10509     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10510     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10511
10512     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10513     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10514     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10515     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10516
10517     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10518     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10519
10520     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10521     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10522
10523     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10524     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10525
10526     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10527     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10528
10529     hr = IDirect3DDevice9_EndScene(device);
10530     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10531
10532     color = getPixelColor(device, 75, 75);
10533     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10534     color = getPixelColor(device, 150, 150);
10535     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10536     color = getPixelColor(device, 320, 240);
10537     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10538     color = getPixelColor(device, 320, 330);
10539     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10540     color = getPixelColor(device, 320, 330);
10541     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10542
10543     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10544     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10545
10546     vp.MinZ = 0.0;
10547     vp.MaxZ = 1.0;
10548     hr = IDirect3DDevice9_SetViewport(device, &vp);
10549     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10550 }
10551
10552 static void depth_buffer_test(IDirect3DDevice9 *device)
10553 {
10554     static const struct vertex quad1[] =
10555     {
10556         { -1.0,  1.0, 0.33f, 0xff00ff00},
10557         {  1.0,  1.0, 0.33f, 0xff00ff00},
10558         { -1.0, -1.0, 0.33f, 0xff00ff00},
10559         {  1.0, -1.0, 0.33f, 0xff00ff00},
10560     };
10561     static const struct vertex quad2[] =
10562     {
10563         { -1.0,  1.0, 0.50f, 0xffff00ff},
10564         {  1.0,  1.0, 0.50f, 0xffff00ff},
10565         { -1.0, -1.0, 0.50f, 0xffff00ff},
10566         {  1.0, -1.0, 0.50f, 0xffff00ff},
10567     };
10568     static const struct vertex quad3[] =
10569     {
10570         { -1.0,  1.0, 0.66f, 0xffff0000},
10571         {  1.0,  1.0, 0.66f, 0xffff0000},
10572         { -1.0, -1.0, 0.66f, 0xffff0000},
10573         {  1.0, -1.0, 0.66f, 0xffff0000},
10574     };
10575     static const DWORD expected_colors[4][4] =
10576     {
10577         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10578         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10579         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10580         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10581     };
10582
10583     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10584     unsigned int i, j;
10585     D3DVIEWPORT9 vp;
10586     D3DCOLOR color;
10587     HRESULT hr;
10588
10589     vp.X = 0;
10590     vp.Y = 0;
10591     vp.Width = 640;
10592     vp.Height = 480;
10593     vp.MinZ = 0.0;
10594     vp.MaxZ = 1.0;
10595
10596     hr = IDirect3DDevice9_SetViewport(device, &vp);
10597     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10598
10599     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10600     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10601     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10602     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10603     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10604     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10605     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10606     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10607     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10608     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10609
10610     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10611     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10612     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10613             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10614     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10615     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10616             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10617     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10618     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10619             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10620     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10621
10622     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10623     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10624     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10625     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10626
10627     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10628     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10629     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10630     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10631
10632     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10633     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10634     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10635     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10636
10637     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10638     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10639     hr = IDirect3DDevice9_BeginScene(device);
10640     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10641     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10642     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10643     hr = IDirect3DDevice9_EndScene(device);
10644     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10645
10646     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10647     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10648     IDirect3DSurface9_Release(backbuffer);
10649     IDirect3DSurface9_Release(rt3);
10650     IDirect3DSurface9_Release(rt2);
10651     IDirect3DSurface9_Release(rt1);
10652
10653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10654     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10655
10656     hr = IDirect3DDevice9_BeginScene(device);
10657     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10658     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10659     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10660     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10661     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10662     hr = IDirect3DDevice9_EndScene(device);
10663     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10664
10665     for (i = 0; i < 4; ++i)
10666     {
10667         for (j = 0; j < 4; ++j)
10668         {
10669             unsigned int x = 80 * ((2 * j) + 1);
10670             unsigned int y = 60 * ((2 * i) + 1);
10671             color = getPixelColor(device, x, y);
10672             ok(color_match(color, expected_colors[i][j], 0),
10673                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10674         }
10675     }
10676
10677     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10678     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10679 }
10680
10681 static void shadow_test(IDirect3DDevice9 *device)
10682 {
10683     static const DWORD ps_code[] =
10684     {
10685         0xffff0200,                                                             /* ps_2_0                       */
10686         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
10687         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
10688         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
10689         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
10690         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
10691         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
10692         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
10693         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
10694         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
10695         0x0000ffff,                                                             /* end                          */
10696     };
10697     struct
10698     {
10699         D3DFORMAT format;
10700         const char *name;
10701     }
10702     formats[] =
10703     {
10704         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
10705         {D3DFMT_D32,            "D3DFMT_D32"},
10706         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
10707         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
10708         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
10709         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
10710         {D3DFMT_D16,            "D3DFMT_D16"},
10711         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
10712         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
10713     };
10714     struct
10715     {
10716         float x, y, z;
10717         float s, t, p, q;
10718     }
10719     quad[] =
10720     {
10721         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
10722         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
10723         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
10724         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
10725     };
10726     struct
10727     {
10728         UINT x, y;
10729         D3DCOLOR color;
10730     }
10731     expected_colors[] =
10732     {
10733         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
10734         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
10735         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
10736         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
10737         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
10738         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
10739         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
10740         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
10741     };
10742
10743     IDirect3DSurface9 *original_ds, *original_rt, *rt;
10744     IDirect3DPixelShader9 *ps;
10745     IDirect3D9 *d3d9;
10746     D3DCAPS9 caps;
10747     HRESULT hr;
10748     UINT i;
10749
10750     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10751     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
10752     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
10753     {
10754         skip("No pixel shader 2.0 support, skipping shadow test.\n");
10755         return;
10756     }
10757
10758     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
10759     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
10760     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
10761     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10762     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
10763     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10764
10765     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
10766             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
10767     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10768     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
10769     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
10770
10771     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
10772     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10773     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10774     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10775     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10776     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10777     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10778     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10780     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10781
10782     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10783     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10784     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10785     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10786     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10787     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10788     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10789     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10790     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10791     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10792
10793     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
10794     {
10795         D3DFORMAT format = formats[i].format;
10796         IDirect3DTexture9 *texture;
10797         IDirect3DSurface9 *ds;
10798         unsigned int j;
10799
10800         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10801                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
10802         if (FAILED(hr)) continue;
10803
10804         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
10805                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
10806         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
10807
10808         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
10809         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
10810
10811         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
10812         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10813
10814         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10815         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10816
10817         IDirect3DDevice9_SetPixelShader(device, NULL);
10818         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10819
10820         /* Setup the depth/stencil surface. */
10821         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10822         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10823
10824         hr = IDirect3DDevice9_BeginScene(device);
10825         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10826         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10827         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10828         hr = IDirect3DDevice9_EndScene(device);
10829         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10830
10831         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
10832         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10833         IDirect3DSurface9_Release(ds);
10834
10835         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
10836         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10837
10838         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10839         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10840
10841         hr = IDirect3DDevice9_SetPixelShader(device, ps);
10842         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10843
10844         /* Do the actual shadow mapping. */
10845         hr = IDirect3DDevice9_BeginScene(device);
10846         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10848         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10849         hr = IDirect3DDevice9_EndScene(device);
10850         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10851
10852         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10853         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10854         IDirect3DTexture9_Release(texture);
10855
10856         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
10857         {
10858             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
10859             ok(color_match(color, expected_colors[j].color, 0),
10860                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
10861                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
10862                     formats[i].name, color);
10863         }
10864
10865         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10866         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10867     }
10868
10869     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10870     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10871     IDirect3DPixelShader9_Release(ps);
10872
10873     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
10874     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10875     IDirect3DSurface9_Release(original_ds);
10876
10877     IDirect3DSurface9_Release(original_rt);
10878     IDirect3DSurface9_Release(rt);
10879
10880     IDirect3D9_Release(d3d9);
10881 }
10882
10883 static void fp_special_test(IDirect3DDevice9 *device)
10884 {
10885     static const DWORD vs_header[] =
10886     {
10887         0xfffe0200,                                                             /* vs_2_0                       */
10888         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
10889         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
10890         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
10891     };
10892
10893     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
10894     static const DWORD vs_pow[] =
10895             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
10896     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
10897     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
10898     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
10899     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
10900     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
10901
10902     static const DWORD vs_footer[] =
10903     {
10904         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
10905         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
10906         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
10907         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
10908         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
10909         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
10910         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
10911         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
10912         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
10913         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
10914         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
10915         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
10916         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
10917         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
10918         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10919         0x0000ffff,                                                             /* end                          */
10920     };
10921
10922     static const struct
10923     {
10924         const char *name;
10925         const DWORD *ops;
10926         DWORD size;
10927         D3DCOLOR color1;
10928         D3DCOLOR color2;
10929     }
10930     vs_body[] =
10931     {
10932         /* The basic ideas here are:
10933          *     2.0 * +/-INF == +/-INF
10934          *     NAN != NAN
10935          *
10936          * The vertex shader value is written to the red component, with 0.0
10937          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
10938          * result in 0x00. The pixel shader value is written to the green
10939          * component, but here 0.0 also results in 0x00. The actual value is
10940          * written to the blue component.
10941          *
10942          * There are at least two different ways for D3D implementations to
10943          * handle this. AMD seems to stick mostly to the D3D documentation,
10944          * and doesn't generate floating point specials in the first place.
10945          * Note that that doesn't just apply to functions like rcp and rsq,
10946          * but also basic mul, add, etc. nVidia seems to generate infinities,
10947          * but then clamp them before sending them to the interpolators. In
10948          * OpenGL these aren't clamped, and interpolating them generates NANs
10949          * in the fragment shader, unless flat shading is used (essentially
10950          * replicating the values instead of interpolating them).
10951          *
10952          * I can't currently explain the nVidia results for pow and nrm.
10953          * They're not specials in the vertex shader, but look like -INF in
10954          * the pixel shader. */
10955         {"log",     vs_log,     sizeof(vs_log),     0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
10956         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff /* +FLT_MAX */,  0x0000ff00 /* ???         */},
10957         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000 /*  0.0     */,  0x0000ff00 /* ???         */},
10958         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
10959         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
10960         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
10961         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
10962     };
10963
10964     static const DWORD ps_code[] =
10965     {
10966         0xffff0200,                                                             /* ps_2_0                       */
10967         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
10968         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
10969         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
10970         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
10971         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
10972         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
10973         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
10974         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
10975         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
10976         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
10977         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
10978         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
10979         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
10980         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
10981         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
10982         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
10983         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
10984         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
10985         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
10986         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
10987         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
10988         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
10989         0x0000ffff,                                                             /* end                          */
10990     };
10991
10992     struct
10993     {
10994         float x, y, z;
10995         float s;
10996     }
10997     quad[] =
10998     {
10999         { -1.0f,  1.0f, 0.0f, 0.0f},
11000         {  1.0f,  1.0f, 1.0f, 0.0f},
11001         { -1.0f, -1.0f, 0.0f, 0.0f},
11002         {  1.0f, -1.0f, 1.0f, 0.0f},
11003     };
11004
11005     IDirect3DPixelShader9 *ps;
11006     UINT body_size = 0;
11007     DWORD *vs_code;
11008     D3DCAPS9 caps;
11009     HRESULT hr;
11010     UINT i;
11011
11012     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11013     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11014     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11015     {
11016         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11017         return;
11018     }
11019
11020     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11021     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11022
11023     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11024     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11025     IDirect3DDevice9_SetPixelShader(device, ps);
11026     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11027
11028     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11029     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11030
11031     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11032     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11033
11034     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11035     {
11036         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11037     }
11038
11039     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11040     memcpy(vs_code, vs_header, sizeof(vs_header));
11041
11042     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11043     {
11044         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11045         IDirect3DVertexShader9 *vs;
11046         D3DCOLOR color;
11047
11048         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11049         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11050         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11051
11052         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11053         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11054         IDirect3DDevice9_SetVertexShader(device, vs);
11055         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11056
11057         hr = IDirect3DDevice9_BeginScene(device);
11058         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11059         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11060         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11061         hr = IDirect3DDevice9_EndScene(device);
11062         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11063
11064         color = getPixelColor(device, 320, 240);
11065         ok(color_match(color, vs_body[i].color1, 1) || color_match(color, vs_body[i].color2, 1),
11066                 "Expected color 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11067                 vs_body[i].color1, vs_body[i].color2, vs_body[i].name, color);
11068
11069         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11070         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11071
11072         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11073         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11074         IDirect3DVertexShader9_Release(vs);
11075     }
11076
11077     HeapFree(GetProcessHeap(), 0, vs_code);
11078
11079     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11080     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11081     IDirect3DPixelShader9_Release(ps);
11082 }
11083
11084 START_TEST(visual)
11085 {
11086     IDirect3DDevice9 *device_ptr;
11087     D3DCAPS9 caps;
11088     HRESULT hr;
11089     DWORD color;
11090
11091     d3d9_handle = LoadLibraryA("d3d9.dll");
11092     if (!d3d9_handle)
11093     {
11094         skip("Could not load d3d9.dll\n");
11095         return;
11096     }
11097
11098     device_ptr = init_d3d9();
11099     if (!device_ptr)
11100     {
11101         skip("Creating the device failed\n");
11102         return;
11103     }
11104
11105     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11106
11107     /* Check for the reliability of the returned data */
11108     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11109     if(FAILED(hr))
11110     {
11111         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11112         goto cleanup;
11113     }
11114
11115     color = getPixelColor(device_ptr, 1, 1);
11116     if(color !=0x00ff0000)
11117     {
11118         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11119         goto cleanup;
11120     }
11121     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11122
11123     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11124     if(FAILED(hr))
11125     {
11126         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11127         goto cleanup;
11128     }
11129
11130     color = getPixelColor(device_ptr, 639, 479);
11131     if(color != 0x0000ddee)
11132     {
11133         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11134         goto cleanup;
11135     }
11136     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11137
11138     /* Now execute the real tests */
11139     depth_clamp_test(device_ptr);
11140     stretchrect_test(device_ptr);
11141     lighting_test(device_ptr);
11142     clear_test(device_ptr);
11143     color_fill_test(device_ptr);
11144     fog_test(device_ptr);
11145     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11146     {
11147         test_cube_wrap(device_ptr);
11148     } else {
11149         skip("No cube texture support\n");
11150     }
11151     z_range_test(device_ptr);
11152     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11153     {
11154         maxmip_test(device_ptr);
11155     }
11156     else
11157     {
11158         skip("No mipmap support\n");
11159     }
11160     offscreen_test(device_ptr);
11161     alpha_test(device_ptr);
11162     shademode_test(device_ptr);
11163     srgbtexture_test(device_ptr);
11164     release_buffer_test(device_ptr);
11165     float_texture_test(device_ptr);
11166     g16r16_texture_test(device_ptr);
11167     pixelshader_blending_test(device_ptr);
11168     texture_transform_flags_test(device_ptr);
11169     autogen_mipmap_test(device_ptr);
11170     fixed_function_decl_test(device_ptr);
11171     conditional_np2_repeat_test(device_ptr);
11172     fixed_function_bumpmap_test(device_ptr);
11173     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11174         stencil_cull_test(device_ptr);
11175     } else {
11176         skip("No two sided stencil support\n");
11177     }
11178     pointsize_test(device_ptr);
11179     tssargtemp_test(device_ptr);
11180     np2_stretch_rect_test(device_ptr);
11181     yuv_color_test(device_ptr);
11182     zwriteenable_test(device_ptr);
11183     alphatest_test(device_ptr);
11184     viewport_test(device_ptr);
11185
11186     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11187     {
11188         test_constant_clamp_vs(device_ptr);
11189         test_compare_instructions(device_ptr);
11190     }
11191     else skip("No vs_1_1 support\n");
11192
11193     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11194     {
11195         test_mova(device_ptr);
11196         loop_index_test(device_ptr);
11197         sincos_test(device_ptr);
11198         sgn_test(device_ptr);
11199         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11200             test_vshader_input(device_ptr);
11201             test_vshader_float16(device_ptr);
11202             stream_test(device_ptr);
11203         } else {
11204             skip("No vs_3_0 support\n");
11205         }
11206     }
11207     else skip("No vs_2_0 support\n");
11208
11209     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11210     {
11211         fog_with_shader_test(device_ptr);
11212     }
11213     else skip("No vs_1_1 and ps_1_1 support\n");
11214
11215     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11216     {
11217         texbem_test(device_ptr);
11218         texdepth_test(device_ptr);
11219         texkill_test(device_ptr);
11220         x8l8v8u8_test(device_ptr);
11221         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11222             constant_clamp_ps_test(device_ptr);
11223             cnd_test(device_ptr);
11224             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11225                 dp2add_ps_test(device_ptr);
11226                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11227                     nested_loop_test(device_ptr);
11228                     fixed_function_varying_test(device_ptr);
11229                     vFace_register_test(device_ptr);
11230                     vpos_register_test(device_ptr);
11231                     multiple_rendertargets_test(device_ptr);
11232                 } else {
11233                     skip("No ps_3_0 or vs_3_0 support\n");
11234                 }
11235             } else {
11236                 skip("No ps_2_0 support\n");
11237             }
11238         }
11239     }
11240     else skip("No ps_1_1 support\n");
11241
11242     texop_test(device_ptr);
11243     texop_range_test(device_ptr);
11244     alphareplicate_test(device_ptr);
11245     dp3_alpha_test(device_ptr);
11246     depth_buffer_test(device_ptr);
11247     shadow_test(device_ptr);
11248     fp_special_test(device_ptr);
11249
11250 cleanup:
11251     if(device_ptr) {
11252         D3DPRESENT_PARAMETERS present_parameters;
11253         IDirect3DSwapChain9 *swapchain;
11254         ULONG ref;
11255
11256         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11257         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11258         IDirect3DSwapChain9_Release(swapchain);
11259         ref = IDirect3DDevice9_Release(device_ptr);
11260         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11261         DestroyWindow(present_parameters.hDeviceWindow);
11262     }
11263 }