shdocvw: Support URLs passed by reference in WebBrowser_Navigate2.
[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_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47     return ret;
48 }
49
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
51 {
52     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53     c1 >>= 8; c2 >>= 8;
54     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55     c1 >>= 8; c2 >>= 8;
56     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57     c1 >>= 8; c2 >>= 8;
58     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59     return TRUE;
60 }
61
62 /* Locks a given surface and returns the color at (x,y).  It's the caller's
63  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
65 {
66     DWORD color;
67     HRESULT hr;
68     D3DSURFACE_DESC desc;
69     RECT rectToLock = {x, y, x+1, y+1};
70     D3DLOCKED_RECT lockedRect;
71
72     hr = IDirect3DSurface9_GetDesc(surface, &desc);
73     if(FAILED(hr))  /* This is not a test */
74     {
75         trace("Can't get the surface description, hr=%08x\n", hr);
76         return 0xdeadbeef;
77     }
78
79     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80     if(FAILED(hr))  /* This is not a test */
81     {
82         trace("Can't lock the surface, hr=%08x\n", hr);
83         return 0xdeadbeef;
84     }
85     switch(desc.Format) {
86         case D3DFMT_A8R8G8B8:
87         {
88             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89             break;
90         }
91         default:
92             trace("Error: unknown surface format: %d\n", desc.Format);
93             color = 0xdeadbeef;
94             break;
95     }
96     hr = IDirect3DSurface9_UnlockRect(surface);
97     if(FAILED(hr))
98     {
99         trace("Can't unlock the surface, hr=%08x\n", hr);
100     }
101     return color;
102 }
103
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
105 {
106     DWORD ret;
107     IDirect3DSurface9 *surf;
108     HRESULT hr;
109     D3DLOCKED_RECT lockedRect;
110     RECT rectToLock = {x, y, x+1, y+1};
111
112     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113     if(FAILED(hr) || !surf )  /* This is not a test */
114     {
115         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116         return 0xdeadbeef;
117     }
118
119     hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120     if(FAILED(hr))
121     {
122         trace("Can't read the front buffer data, hr=%08x\n", hr);
123         ret = 0xdeadbeed;
124         goto out;
125     }
126
127     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128     if(FAILED(hr))
129     {
130         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131         ret = 0xdeadbeec;
132         goto out;
133     }
134
135     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136      * really important for these tests
137      */
138     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139     hr = IDirect3DSurface9_UnlockRect(surf);
140     if(FAILED(hr))
141     {
142         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
143     }
144
145 out:
146     if(surf) IDirect3DSurface9_Release(surf);
147     return ret;
148 }
149
150 static IDirect3DDevice9 *init_d3d9(void)
151 {
152     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153     IDirect3D9 *d3d9_ptr = 0;
154     IDirect3DDevice9 *device_ptr = 0;
155     D3DPRESENT_PARAMETERS present_parameters;
156     HRESULT hr;
157     D3DADAPTER_IDENTIFIER9 identifier;
158
159     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161     if (!d3d9_create) return NULL;
162
163     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164     if (!d3d9_ptr)
165     {
166         skip("could not create D3D9\n");
167         return NULL;
168     }
169
170     ZeroMemory(&present_parameters, sizeof(present_parameters));
171     present_parameters.Windowed = FALSE;
172     present_parameters.hDeviceWindow = create_window();
173     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174     present_parameters.BackBufferWidth = 640;
175     present_parameters.BackBufferHeight = 480;
176     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177     present_parameters.EnableAutoDepthStencil = TRUE;
178     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
179
180     memset(&identifier, 0, sizeof(identifier));
181     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183     trace("Driver string: \"%s\"\n", identifier.Driver);
184     trace("Description string: \"%s\"\n", identifier.Description);
185     ok(identifier.Description[0] != '\0', "Empty driver description\n");
186     trace("Device name string: \"%s\"\n", identifier.DeviceName);
187     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
188     trace("Driver version %d.%d.%d.%d\n",
189           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
190           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
191
192     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
193     if(FAILED(hr)) {
194         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
195         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196         if(FAILED(hr)) {
197             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
198         }
199     }
200     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
201
202     return device_ptr;
203 }
204
205 struct vertex
206 {
207     float x, y, z;
208     DWORD diffuse;
209 };
210
211 struct tvertex
212 {
213     float x, y, z, rhw;
214     DWORD diffuse;
215 };
216
217 struct nvertex
218 {
219     float x, y, z;
220     float nx, ny, nz;
221     DWORD diffuse;
222 };
223
224 static void lighting_test(IDirect3DDevice9 *device)
225 {
226     HRESULT hr;
227     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
228     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
229     DWORD color;
230     D3DMATERIAL9 material, old_material;
231     DWORD cop, carg;
232
233     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
234                       0.0f, 1.0f, 0.0f, 0.0f,
235                       0.0f, 0.0f, 1.0f, 0.0f,
236                       0.0f, 0.0f, 0.0f, 1.0f };
237
238     struct vertex unlitquad[] =
239     {
240         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
241         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
242         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
243         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
244     };
245     struct vertex litquad[] =
246     {
247         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
248         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
249         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
250         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
251     };
252     struct nvertex unlitnquad[] =
253     {
254         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
255         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
256         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
257         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
258     };
259     struct nvertex litnquad[] =
260     {
261         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
262         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
263         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
264         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
265     };
266     WORD Indices[] = {0, 1, 2, 2, 3, 0};
267
268     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
269     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
270
271     /* Setup some states that may cause issues */
272     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
278     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
279     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
281     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
296
297     hr = IDirect3DDevice9_SetFVF(device, 0);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
299
300     hr = IDirect3DDevice9_SetFVF(device, fvf);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
302
303     hr = IDirect3DDevice9_BeginScene(device);
304     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
305     if(hr == D3D_OK)
306     {
307         /* No lights are defined... That means, lit vertices should be entirely black */
308         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
309         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
310         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
312         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
313
314         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
315         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
316         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
317                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
318         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
319
320         hr = IDirect3DDevice9_SetFVF(device, nfvf);
321         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
322
323         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
324         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
325         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
326                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
327         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
328
329         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
330         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
331         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
332                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
333         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
334
335         IDirect3DDevice9_EndScene(device);
336         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
337     }
338
339     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
340
341     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
342     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
343     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
344     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
345     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
346     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
347     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
348     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
349
350     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
351     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
352     memset(&material, 0, sizeof(material));
353     material.Diffuse.r = 0.0;
354     material.Diffuse.g = 0.0;
355     material.Diffuse.b = 0.0;
356     material.Diffuse.a = 1.0;
357     material.Ambient.r = 0.0;
358     material.Ambient.g = 0.0;
359     material.Ambient.b = 0.0;
360     material.Ambient.a = 0.0;
361     material.Specular.r = 0.0;
362     material.Specular.g = 0.0;
363     material.Specular.b = 0.0;
364     material.Specular.a = 0.0;
365     material.Emissive.r = 0.0;
366     material.Emissive.g = 0.0;
367     material.Emissive.b = 0.0;
368     material.Emissive.a = 0.0;
369     material.Power = 0.0;
370     IDirect3DDevice9_SetMaterial(device, &material);
371     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
372
373     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
374     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
375     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
376     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
377
378     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
379     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
381     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
382     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
384     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
386
387     hr = IDirect3DDevice9_BeginScene(device);
388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
389     if(SUCCEEDED(hr)) {
390         struct vertex lighting_test[] = {
391             {-1.0,   -1.0,   0.1,    0x8000ff00},
392             { 1.0,   -1.0,   0.1,    0x80000000},
393             {-1.0,    1.0,   0.1,    0x8000ff00},
394             { 1.0,    1.0,   0.1,    0x80000000}
395         };
396         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
397         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
398         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
399         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
400
401         hr = IDirect3DDevice9_EndScene(device);
402         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
403     }
404
405     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
406     color = getPixelColor(device, 320, 240);
407     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
408
409     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
414     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
417     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
418     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
419     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
421 }
422
423 static void clear_test(IDirect3DDevice9 *device)
424 {
425     /* Tests the correctness of clearing parameters */
426     HRESULT hr;
427     D3DRECT rect[2];
428     D3DRECT rect_negneg;
429     DWORD color;
430     D3DVIEWPORT9 old_vp, vp;
431     RECT scissor;
432     DWORD oldColorWrite;
433     BOOL invalid_clear_failed = FALSE;
434
435     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
436     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
437
438     /* Positive x, negative y */
439     rect[0].x1 = 0;
440     rect[0].y1 = 480;
441     rect[0].x2 = 320;
442     rect[0].y2 = 240;
443
444     /* Positive x, positive y */
445     rect[1].x1 = 0;
446     rect[1].y1 = 0;
447     rect[1].x2 = 320;
448     rect[1].y2 = 240;
449     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
450      * returns D3D_OK, but ignores the rectangle silently
451      */
452     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
453     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
454     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
455
456     /* negative x, negative y */
457     rect_negneg.x1 = 640;
458     rect_negneg.y1 = 240;
459     rect_negneg.x2 = 320;
460     rect_negneg.y2 = 0;
461     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
462     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
463     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
464
465     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
466
467     color = getPixelColor(device, 160, 360); /* lower left quad */
468     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
469     color = getPixelColor(device, 160, 120); /* upper left quad */
470     if(invalid_clear_failed) {
471         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
472         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
473     } else {
474         /* If the negative rectangle was dropped silently, the correct ones are cleared */
475         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
476     }
477     color = getPixelColor(device, 480, 360); /* lower right quad  */
478     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
479     color = getPixelColor(device, 480, 120); /* upper right quad */
480     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
481
482     /* Test how the viewport affects clears */
483     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
484     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
485     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
486     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
487
488     vp.X = 160;
489     vp.Y = 120;
490     vp.Width = 160;
491     vp.Height = 120;
492     vp.MinZ = 0.0;
493     vp.MaxZ = 1.0;
494     hr = IDirect3DDevice9_SetViewport(device, &vp);
495     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
496     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
497     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
498
499     vp.X = 320;
500     vp.Y = 240;
501     vp.Width = 320;
502     vp.Height = 240;
503     vp.MinZ = 0.0;
504     vp.MaxZ = 1.0;
505     hr = IDirect3DDevice9_SetViewport(device, &vp);
506     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
507     rect[0].x1 = 160;
508     rect[0].y1 = 120;
509     rect[0].x2 = 480;
510     rect[0].y2 = 360;
511     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
512     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
513
514     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
515     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
516
517     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
518     color = getPixelColor(device, 158, 118);
519     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
520     color = getPixelColor(device, 162, 118);
521     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
522     color = getPixelColor(device, 158, 122);
523     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
524     color = getPixelColor(device, 162, 122);
525     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
526
527     color = getPixelColor(device, 318, 238);
528     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
529     color = getPixelColor(device, 322, 238);
530     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
531     color = getPixelColor(device, 318, 242);
532     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
533     color = getPixelColor(device, 322, 242);
534     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
535
536     color = getPixelColor(device, 478, 358);
537     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
538     color = getPixelColor(device, 482, 358);
539     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
540     color = getPixelColor(device, 478, 362);
541     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
542     color = getPixelColor(device, 482, 362);
543     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
544
545     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
546     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
547
548     scissor.left = 160;
549     scissor.right = 480;
550     scissor.top = 120;
551     scissor.bottom = 360;
552     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
553     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
555     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
556
557     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
558     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
563     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566     color = getPixelColor(device, 158, 118);
567     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
568     color = getPixelColor(device, 162, 118);
569     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
570     color = getPixelColor(device, 158, 122);
571     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
572     color = getPixelColor(device, 162, 122);
573     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
574
575     color = getPixelColor(device, 158, 358);
576     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
577     color = getPixelColor(device, 162, 358);
578     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
579     color = getPixelColor(device, 158, 358);
580     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
581     color = getPixelColor(device, 162, 362);
582     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
583
584     color = getPixelColor(device, 478, 118);
585     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
586     color = getPixelColor(device, 478, 122);
587     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
588     color = getPixelColor(device, 482, 122);
589     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
590     color = getPixelColor(device, 482, 358);
591     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
592
593     color = getPixelColor(device, 478, 358);
594     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
595     color = getPixelColor(device, 478, 362);
596     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
597     color = getPixelColor(device, 482, 358);
598     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
599     color = getPixelColor(device, 482, 362);
600     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
601
602     color = getPixelColor(device, 318, 238);
603     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
604     color = getPixelColor(device, 318, 242);
605     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
606     color = getPixelColor(device, 322, 238);
607     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
608     color = getPixelColor(device, 322, 242);
609     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
610
611     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
612     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
614     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
615
616     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
617     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
618
619     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
620     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
621
622     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
623
624     /* Colorwriteenable does not affect the clear */
625     color = getPixelColor(device, 320, 240);
626     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
627 }
628
629 typedef struct {
630     float in[4];
631     DWORD out;
632 } test_data_t;
633
634 /*
635  *  c7      mova    ARGB            mov     ARGB
636  * -2.4     -2      0x00ffff00      -3      0x00ff0000
637  * -1.6     -2      0x00ffff00      -2      0x00ffff00
638  * -0.4      0      0x0000ffff      -1      0x0000ff00
639  *  0.4      0      0x0000ffff       0      0x0000ffff
640  *  1.6      2      0x00ff00ff       1      0x000000ff
641  *  2.4      2      0x00ff00ff       2      0x00ff00ff
642  */
643 static void test_mova(IDirect3DDevice9 *device)
644 {
645     static const DWORD mova_test[] = {
646         0xfffe0200,                                                             /* vs_2_0                       */
647         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
648         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
649         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
650         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
651         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
652         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
653         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
654         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
655         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
656         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
657         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
658         0x0000ffff                                                              /* END                          */
659     };
660     static const DWORD mov_test[] = {
661         0xfffe0101,                                                             /* vs_1_1                       */
662         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
663         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
664         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
665         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
666         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
667         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
668         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
669         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
670         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
671         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
672         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
673         0x0000ffff                                                              /* END                          */
674     };
675
676     static const test_data_t test_data[2][6] = {
677         {
678             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
679             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
680             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
681             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
682             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
683             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
684         },
685         {
686             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
687             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
688             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
689             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
690             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
691             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
692         }
693     };
694
695     static const float quad[][3] = {
696         {-1.0f, -1.0f, 0.0f},
697         {-1.0f,  1.0f, 0.0f},
698         { 1.0f, -1.0f, 0.0f},
699         { 1.0f,  1.0f, 0.0f},
700     };
701
702     static const D3DVERTEXELEMENT9 decl_elements[] = {
703         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
704         D3DDECL_END()
705     };
706
707     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
708     IDirect3DVertexShader9 *mova_shader = NULL;
709     IDirect3DVertexShader9 *mov_shader = NULL;
710     HRESULT hr;
711     UINT i, j;
712
713     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
714     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
716     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
717     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
718     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
719     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
720     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
721
722     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
723     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
724     for(j = 0; j < 2; ++j)
725     {
726         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
727         {
728             DWORD color;
729
730             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
731             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
732
733             hr = IDirect3DDevice9_BeginScene(device);
734             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
735
736             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
737             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
738
739             hr = IDirect3DDevice9_EndScene(device);
740             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
741
742             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
743             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
744
745             color = getPixelColor(device, 320, 240);
746             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
747                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
748
749             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
750             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
751         }
752         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
753         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
754     }
755
756     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
757     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
758
759     IDirect3DVertexDeclaration9_Release(vertex_declaration);
760     IDirect3DVertexShader9_Release(mova_shader);
761     IDirect3DVertexShader9_Release(mov_shader);
762 }
763
764 struct sVertex {
765     float x, y, z;
766     DWORD diffuse;
767     DWORD specular;
768 };
769
770 struct sVertexT {
771     float x, y, z, rhw;
772     DWORD diffuse;
773     DWORD specular;
774 };
775
776 static void fog_test(IDirect3DDevice9 *device)
777 {
778     HRESULT hr;
779     D3DCOLOR color;
780     float start = 0.0f, end = 1.0f;
781     D3DCAPS9 caps;
782     int i;
783
784     /* Gets full z based fog with linear fog, no fog with specular color */
785     struct sVertex unstransformed_1[] = {
786         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
787         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
788         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
789         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
790     };
791     /* Ok, I am too lazy to deal with transform matrices */
792     struct sVertex unstransformed_2[] = {
793         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
794         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
795         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
796         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
797     };
798     /* Untransformed ones. Give them a different diffuse color to make the test look
799      * nicer. It also makes making sure that they are drawn correctly easier.
800      */
801     struct sVertexT transformed_1[] = {
802         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
803         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
804         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
805         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
806     };
807     struct sVertexT transformed_2[] = {
808         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
809         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
810         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
811         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
812     };
813     struct vertex rev_fog_quads[] = {
814        {-1.0,   -1.0,   0.1,    0x000000ff},
815        {-1.0,    0.0,   0.1,    0x000000ff},
816        { 0.0,    0.0,   0.1,    0x000000ff},
817        { 0.0,   -1.0,   0.1,    0x000000ff},
818
819        { 0.0,   -1.0,   0.9,    0x000000ff},
820        { 0.0,    0.0,   0.9,    0x000000ff},
821        { 1.0,    0.0,   0.9,    0x000000ff},
822        { 1.0,   -1.0,   0.9,    0x000000ff},
823
824        { 0.0,    0.0,   0.4,    0x000000ff},
825        { 0.0,    1.0,   0.4,    0x000000ff},
826        { 1.0,    1.0,   0.4,    0x000000ff},
827        { 1.0,    0.0,   0.4,    0x000000ff},
828
829        {-1.0,    0.0,   0.7,    0x000000ff},
830        {-1.0,    1.0,   0.7,    0x000000ff},
831        { 0.0,    1.0,   0.7,    0x000000ff},
832        { 0.0,    0.0,   0.7,    0x000000ff},
833     };
834     WORD Indices[] = {0, 1, 2, 2, 3, 0};
835
836     memset(&caps, 0, sizeof(caps));
837     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
838     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
839     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
840     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
841
842     /* Setup initial states: No lighting, fog on, fog color */
843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
844     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
845     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
846     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
847     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
848     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
849
850     /* First test: Both table fog and vertex fog off */
851     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
852     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
853     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
854     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
855
856     /* Start = 0, end = 1. Should be default, but set them */
857     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
858     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
859     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
860     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
861
862     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
863     {
864         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
865         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
866         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
867         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
868                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
869                                                      sizeof(unstransformed_1[0]));
870         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
871
872         /* That makes it use the Z value */
873         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
874         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
875         /* Untransformed, vertex fog != none (or table fog != none):
876          * Use the Z value as input into the equation
877          */
878         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
879                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
880                                                      sizeof(unstransformed_1[0]));
881         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
882
883         /* transformed verts */
884         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
885         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
886         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
887         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
888                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
889                                                      sizeof(transformed_1[0]));
890         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
891
892         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
893         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
894         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
895          * equation
896          */
897         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
898                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
899                                                      sizeof(transformed_2[0]));
900
901         hr = IDirect3DDevice9_EndScene(device);
902         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
903     }
904     else
905     {
906         ok(FALSE, "BeginScene failed\n");
907     }
908
909     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
910     color = getPixelColor(device, 160, 360);
911     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
912     color = getPixelColor(device, 160, 120);
913     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
914     color = getPixelColor(device, 480, 120);
915     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
916     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
917     {
918         color = getPixelColor(device, 480, 360);
919         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
920     }
921     else
922     {
923         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
924          * The settings above result in no fogging with vertex fog
925          */
926         color = getPixelColor(device, 480, 120);
927         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
928         trace("Info: Table fog not supported by this device\n");
929     }
930
931     /* Now test the special case fogstart == fogend */
932     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
933     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
934
935     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
936     {
937         start = 512;
938         end = 512;
939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
940         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
941         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
942         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
943
944         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
945         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
946         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
947         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
948         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
949         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
950
951         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
952          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
953          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
954          * The third transformed quad remains unfogged because the fogcoords are read from the specular
955          * color and has fixed fogstart and fogend.
956          */
957         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
959                 sizeof(unstransformed_1[0]));
960         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
961         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
962                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
963                 sizeof(unstransformed_1[0]));
964         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
965
966         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
967         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
968         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
969         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
970                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
971                 sizeof(transformed_1[0]));
972         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
973
974         hr = IDirect3DDevice9_EndScene(device);
975         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
976     }
977     else
978     {
979         ok(FALSE, "BeginScene failed\n");
980     }
981     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
982     color = getPixelColor(device, 160, 360);
983     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
984     color = getPixelColor(device, 160, 120);
985     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
986     color = getPixelColor(device, 480, 120);
987     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
988
989     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
990      * but without shaders it seems to work everywhere
991      */
992     end = 0.2;
993     start = 0.8;
994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
995     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
996     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
997     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
998     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
999     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1000
1001     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1002      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1003      * so skip this for now
1004      */
1005     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1006         const char *mode = (i ? "table" : "vertex");
1007         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1008         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1009         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1010         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1011         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1012         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1013         hr = IDirect3DDevice9_BeginScene(device);
1014         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1015         if(SUCCEEDED(hr)) {
1016             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1017                                 4,  5,  6,  6,  7, 4,
1018                                 8,  9, 10, 10, 11, 8,
1019                             12, 13, 14, 14, 15, 12};
1020
1021             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1022                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1023                     sizeof(rev_fog_quads[0]));
1024
1025             hr = IDirect3DDevice9_EndScene(device);
1026             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1027         }
1028         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1029         color = getPixelColor(device, 160, 360);
1030         ok(color_match(color, 0x0000ff00, 1),
1031                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1032
1033         color = getPixelColor(device, 160, 120);
1034         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1035                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1036
1037         color = getPixelColor(device, 480, 120);
1038         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1039                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1040
1041         color = getPixelColor(device, 480, 360);
1042         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1043
1044         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1045             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1046             break;
1047         }
1048     }
1049     /* Turn off the fog master switch to avoid confusing other tests */
1050     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1051     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1052     start = 0.0;
1053     end = 1.0;
1054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1055     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1057     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1059     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1061     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1062 }
1063
1064 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1065  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1066  * regardless of the actual addressing mode set. */
1067 static void test_cube_wrap(IDirect3DDevice9 *device)
1068 {
1069     static const float quad[][6] = {
1070         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1071         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1072         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1073         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1074     };
1075
1076     static const D3DVERTEXELEMENT9 decl_elements[] = {
1077         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1078         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1079         D3DDECL_END()
1080     };
1081
1082     static const struct {
1083         D3DTEXTUREADDRESS mode;
1084         const char *name;
1085     } address_modes[] = {
1086         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1087         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1088         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1089         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1090         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1091     };
1092
1093     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1094     IDirect3DCubeTexture9 *texture = NULL;
1095     IDirect3DSurface9 *surface = NULL;
1096     D3DLOCKED_RECT locked_rect;
1097     HRESULT hr;
1098     UINT x;
1099     INT y, face;
1100
1101     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1102     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1103     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1104     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1105
1106     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1107             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1108     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1109
1110     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1111     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1112
1113     for (y = 0; y < 128; ++y)
1114     {
1115         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1116         for (x = 0; x < 64; ++x)
1117         {
1118             *ptr++ = 0xffff0000;
1119         }
1120         for (x = 64; x < 128; ++x)
1121         {
1122             *ptr++ = 0xff0000ff;
1123         }
1124     }
1125
1126     hr = IDirect3DSurface9_UnlockRect(surface);
1127     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1128
1129     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1130             D3DPOOL_DEFAULT, &texture, NULL);
1131     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1132
1133     /* Create cube faces */
1134     for (face = 0; face < 6; ++face)
1135     {
1136         IDirect3DSurface9 *face_surface = NULL;
1137
1138         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1139         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1140
1141         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1142         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1143
1144         IDirect3DSurface9_Release(face_surface);
1145     }
1146
1147     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1148     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1149
1150     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1151     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1152     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1153     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1154     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1155     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1156
1157     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1158     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1159
1160     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1161     {
1162         DWORD color;
1163
1164         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1165         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1166         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1167         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1168
1169         hr = IDirect3DDevice9_BeginScene(device);
1170         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1171
1172         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1173         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1174
1175         hr = IDirect3DDevice9_EndScene(device);
1176         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1177
1178         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1179         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1180
1181         /* Due to the nature of this test, we sample essentially at the edge
1182          * between two faces. Because of this it's undefined from which face
1183          * the driver will sample. Fortunately that's not important for this
1184          * test, since all we care about is that it doesn't sample from the
1185          * other side of the surface or from the border. */
1186         color = getPixelColor(device, 320, 240);
1187         ok(color == 0x00ff0000 || color == 0x000000ff,
1188                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1189                 color, address_modes[x].name);
1190
1191         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1192         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1193     }
1194
1195     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1196     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1197
1198     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1199     IDirect3DCubeTexture9_Release(texture);
1200     IDirect3DSurface9_Release(surface);
1201 }
1202
1203 static void offscreen_test(IDirect3DDevice9 *device)
1204 {
1205     HRESULT hr;
1206     IDirect3DTexture9 *offscreenTexture = NULL;
1207     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1208     DWORD color;
1209
1210     static const float quad[][5] = {
1211         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1212         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1213         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1214         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1215     };
1216
1217     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1218     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1219
1220     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1221     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1222     if(!offscreenTexture) {
1223         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1224         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1225         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1226         if(!offscreenTexture) {
1227             skip("Cannot create an offscreen render target\n");
1228             goto out;
1229         }
1230     }
1231
1232     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1233     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1234     if(!backbuffer) {
1235         goto out;
1236     }
1237
1238     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1239     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1240     if(!offscreen) {
1241         goto out;
1242     }
1243
1244     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1245     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1246
1247     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1248     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1249     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1250     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1251     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1252     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1253     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1254     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1255     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1256     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1257
1258     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1259         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1260         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1261         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1262         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1263
1264         /* Draw without textures - Should result in a white quad */
1265         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1266         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1267
1268         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1269         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1270         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1271         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1272
1273         /* This time with the texture */
1274         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1275         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1276
1277         IDirect3DDevice9_EndScene(device);
1278     }
1279
1280     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1281
1282     /* Center quad - should be white */
1283     color = getPixelColor(device, 320, 240);
1284     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1285     /* Some quad in the cleared part of the texture */
1286     color = getPixelColor(device, 170, 240);
1287     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1288     /* Part of the originally cleared back buffer */
1289     color = getPixelColor(device, 10, 10);
1290     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1291     if(0) {
1292         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1293          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1294          * the offscreen rendering mode this test would succeed or fail
1295          */
1296         color = getPixelColor(device, 10, 470);
1297         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1298     }
1299
1300 out:
1301     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1302
1303     /* restore things */
1304     if(backbuffer) {
1305         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1306         IDirect3DSurface9_Release(backbuffer);
1307     }
1308     if(offscreenTexture) {
1309         IDirect3DTexture9_Release(offscreenTexture);
1310     }
1311     if(offscreen) {
1312         IDirect3DSurface9_Release(offscreen);
1313     }
1314 }
1315
1316 /* This test tests fog in combination with shaders.
1317  * What's tested: linear fog (vertex and table) with pixel shader
1318  *                linear table fog with non foggy vertex shader
1319  *                vertex fog with foggy vertex shader, non-linear
1320  *                fog with shader, non-linear fog with foggy shader,
1321  *                linear table fog with foggy shader
1322  */
1323 static void fog_with_shader_test(IDirect3DDevice9 *device)
1324 {
1325     HRESULT hr;
1326     DWORD color;
1327     union {
1328         float f;
1329         DWORD i;
1330     } start, end;
1331     unsigned int i, j;
1332
1333     /* basic vertex shader without fog computation ("non foggy") */
1334     static const DWORD vertex_shader_code1[] = {
1335         0xfffe0101,                                                             /* vs_1_1                       */
1336         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1337         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1338         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1339         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1340         0x0000ffff
1341     };
1342     /* basic vertex shader with reversed fog computation ("foggy") */
1343     static const DWORD vertex_shader_code2[] = {
1344         0xfffe0101,                                                             /* vs_1_1                        */
1345         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1346         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1347         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1348         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1349         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1350         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1351         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1352         0x0000ffff
1353     };
1354     /* basic pixel shader */
1355     static const DWORD pixel_shader_code[] = {
1356         0xffff0101,                                                             /* ps_1_1     */
1357         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1358         0x0000ffff
1359     };
1360
1361     static struct vertex quad[] = {
1362         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1363         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1364         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1365         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1366     };
1367
1368     static const D3DVERTEXELEMENT9 decl_elements[] = {
1369         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1370         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1371         D3DDECL_END()
1372     };
1373
1374     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1375     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1376     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1377
1378     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1379     static const struct test_data_t {
1380         int vshader;
1381         int pshader;
1382         D3DFOGMODE vfog;
1383         D3DFOGMODE tfog;
1384         unsigned int color[11];
1385     } test_data[] = {
1386         /* only pixel shader: */
1387         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1388         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1389         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1390         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1391         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1392         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1393         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1394         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1395         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1396         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1397         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1398         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1399         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1400         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1401         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1402
1403         /* vertex shader */
1404         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1405         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1406          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1407         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1408         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1411         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1413
1414         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1415         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1417         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1418         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1419         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1420
1421         /* vertex shader and pixel shader */
1422         /* The next 4 tests would read the fog coord output, but it isn't available.
1423          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1424          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1425          * These tests should be disabled if some other hardware behaves differently
1426          */
1427         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1428         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1429         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1430         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1431         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1432         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1433         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1434         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1435         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1436         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1437         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1438         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1439
1440         /* These use the Z coordinate with linear table fog */
1441         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1442         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1443         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1444         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1445         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1446         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1447         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1448         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1449         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1450         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1451         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1452         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1453
1454         /* Non-linear table fog without fog coord */
1455         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1456         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1457         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1458         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1459         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1460         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1461
1462 #if 0  /* FIXME: these fail on GeForce 8500 */
1463         /* foggy vertex shader */
1464         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1465         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1468         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1470         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1471         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1472          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1473         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1474         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1475          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1476 #endif
1477
1478         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1479          * all using the fixed fog-coord linear fog
1480          */
1481         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1482         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1483          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1484         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1485         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1488         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1491         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493
1494         /* These use table fog. Here the shader-provided fog coordinate is
1495          * ignored and the z coordinate used instead
1496          */
1497         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1498         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1499         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1500         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1501         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1502         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1503         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506     };
1507
1508     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1509     start.f=0.1f;
1510     end.f=0.9f;
1511
1512     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1513     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1514     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1515     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1516     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1517     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1518     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1519     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1520
1521     /* Setup initial states: No lighting, fog on, fog color */
1522     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1523     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1524     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1525     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1527     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1528     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1529     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1530
1531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1532     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1533     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1534     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1535
1536     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1538     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1539     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1540     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1541
1542     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1543     {
1544         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1545         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1546         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1547         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1548         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1549         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1550         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1551         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1552
1553         for(j=0; j < 11; j++)
1554         {
1555             /* Don't use the whole zrange to prevent rounding errors */
1556             quad[0].z = 0.001f + (float)j / 10.02f;
1557             quad[1].z = 0.001f + (float)j / 10.02f;
1558             quad[2].z = 0.001f + (float)j / 10.02f;
1559             quad[3].z = 0.001f + (float)j / 10.02f;
1560
1561             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1562             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1563
1564             hr = IDirect3DDevice9_BeginScene(device);
1565             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1566
1567             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1568             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1569
1570             hr = IDirect3DDevice9_EndScene(device);
1571             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1572
1573             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1574
1575             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1576             color = getPixelColor(device, 128, 240);
1577             ok(color_match(color, test_data[i].color[j], 13),
1578                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1579                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1580         }
1581     }
1582
1583     /* reset states */
1584     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1585     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1586     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1587     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1588     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1589     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1590     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1591     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1592
1593     IDirect3DVertexShader9_Release(vertex_shader[1]);
1594     IDirect3DVertexShader9_Release(vertex_shader[2]);
1595     IDirect3DPixelShader9_Release(pixel_shader[1]);
1596     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1597 }
1598
1599 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1600     unsigned int i, x, y;
1601     HRESULT hr;
1602     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1603     D3DLOCKED_RECT locked_rect;
1604
1605     /* Generate the textures */
1606     for(i=0; i<2; i++)
1607     {
1608         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1609                                             D3DPOOL_MANAGED, &texture[i], NULL);
1610         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1611
1612         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1613         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1614         for (y = 0; y < 128; ++y)
1615         {
1616             if(i)
1617             { /* Set up black texture with 2x2 texel white spot in the middle */
1618                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1619                 for (x = 0; x < 128; ++x)
1620                 {
1621                     if(y>62 && y<66 && x>62 && x<66)
1622                         *ptr++ = 0xffffffff;
1623                     else
1624                         *ptr++ = 0xff000000;
1625                 }
1626             }
1627             else
1628             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1629                * (if multiplied with bumpenvmat)
1630               */
1631                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1632                 for (x = 0; x < 128; ++x)
1633                 {
1634                     if(abs(x-64)>abs(y-64))
1635                     {
1636                         if(x < 64)
1637                             *ptr++ = 0xc000;
1638                         else
1639                             *ptr++ = 0x4000;
1640                     }
1641                     else
1642                     {
1643                         if(y < 64)
1644                             *ptr++ = 0x0040;
1645                         else
1646                             *ptr++ = 0x00c0;
1647                     }
1648                 }
1649             }
1650         }
1651         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1652         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1653
1654         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1655         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1656
1657         /* Disable texture filtering */
1658         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1659         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1661         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1662
1663         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1664         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1665         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1666         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1667     }
1668 }
1669
1670 /* test the behavior of the texbem instruction
1671  * with normal 2D and projective 2D textures
1672  */
1673 static void texbem_test(IDirect3DDevice9 *device)
1674 {
1675     HRESULT hr;
1676     DWORD color;
1677     int i;
1678
1679     static const DWORD pixel_shader_code[] = {
1680         0xffff0101,                         /* ps_1_1*/
1681         0x00000042, 0xb00f0000,             /* tex t0*/
1682         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1683         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1684         0x0000ffff
1685     };
1686     static const DWORD double_texbem_code[] =  {
1687         0xffff0103,                                         /* ps_1_3           */
1688         0x00000042, 0xb00f0000,                             /* tex t0           */
1689         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1690         0x00000042, 0xb00f0002,                             /* tex t2           */
1691         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1692         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1693         0x0000ffff                                          /* end              */
1694     };
1695
1696
1697     static const float quad[][7] = {
1698         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1699         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1700         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1701         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1702     };
1703     static const float quad_proj[][9] = {
1704         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1705         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1706         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1707         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1708     };
1709
1710     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1711         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1712         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1713         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1714         D3DDECL_END()
1715     },{
1716         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1717         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1718         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1719         D3DDECL_END()
1720     } };
1721
1722     /* use asymmetric matrix to test loading */
1723     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1724
1725     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1726     IDirect3DPixelShader9       *pixel_shader       = NULL;
1727     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1728     D3DLOCKED_RECT locked_rect;
1729
1730     generate_bumpmap_textures(device);
1731
1732     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1733     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1734     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1735     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1736     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1737
1738     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1739     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1740
1741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1743
1744     for(i=0; i<2; i++)
1745     {
1746         if(i)
1747         {
1748             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1749             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1750         }
1751
1752         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1753         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1754         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1755         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1756
1757         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1758         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1759         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1760         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1761
1762         hr = IDirect3DDevice9_BeginScene(device);
1763         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1764
1765         if(!i)
1766             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1767         else
1768             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1769         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1770
1771         hr = IDirect3DDevice9_EndScene(device);
1772         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1773
1774         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1775         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1776
1777         color = getPixelColor(device, 320-32, 240);
1778         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1779         color = getPixelColor(device, 320+32, 240);
1780         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1781         color = getPixelColor(device, 320, 240-32);
1782         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783         color = getPixelColor(device, 320, 240+32);
1784         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1785
1786         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1787         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1788         IDirect3DPixelShader9_Release(pixel_shader);
1789
1790         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1791         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1792         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1793     }
1794
1795     /* clean up */
1796     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1797     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1798
1799     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1800     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1801
1802     for(i=0; i<2; i++)
1803     {
1804         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1805         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1806         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1807         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1808         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1809         IDirect3DTexture9_Release(texture);
1810     }
1811
1812     /* Test double texbem */
1813     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1814     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1815     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1816     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1817     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1818     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1819     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1820     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1821
1822     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1823     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1824     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1825     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1826
1827     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1828     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1829
1830     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1831     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1832     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1833     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1834     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1835     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836
1837     {
1838         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1839 #define tex  0x00ff0000
1840 #define tex1 0x0000ff00
1841 #define origin 0x000000ff
1842         static const DWORD pixel_data[] = {
1843             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1844             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1845             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1846             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1847             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1848             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1851         };
1852 #undef tex1
1853 #undef tex2
1854 #undef origin
1855
1856         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1857         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1858         for(i = 0; i < 8; i++) {
1859             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1860         }
1861         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1862         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1863     }
1864
1865     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1866     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1867     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1868     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1869     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1870     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1872     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1873     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1874     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1875     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1876     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1877
1878     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1879     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1880     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1881     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1882     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1883     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1884
1885     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1886     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1887     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1888     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1889     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1890     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1891
1892     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1893     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1894     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1895     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1896     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1897     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1898     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1899     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1900
1901     hr = IDirect3DDevice9_BeginScene(device);
1902     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1903     if(SUCCEEDED(hr)) {
1904         static const float double_quad[] = {
1905             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1906              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1907             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1908              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1909         };
1910
1911         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1912         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1913         hr = IDirect3DDevice9_EndScene(device);
1914         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1915     }
1916     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1917     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1918     color = getPixelColor(device, 320, 240);
1919     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1920
1921     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1922     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1923     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1930     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1931
1932     IDirect3DPixelShader9_Release(pixel_shader);
1933     IDirect3DTexture9_Release(texture);
1934     IDirect3DTexture9_Release(texture1);
1935     IDirect3DTexture9_Release(texture2);
1936 }
1937
1938 static void z_range_test(IDirect3DDevice9 *device)
1939 {
1940     const struct vertex quad[] =
1941     {
1942         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1943         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1944         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1945         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1946     };
1947     const struct vertex quad2[] =
1948     {
1949         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1950         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1951         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1952         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1953     };
1954
1955     const struct tvertex quad3[] =
1956     {
1957         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1958         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1959         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1960         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1961     };
1962     const struct tvertex quad4[] =
1963     {
1964         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1965         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1966         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1967         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1968     };
1969     HRESULT hr;
1970     DWORD color;
1971     IDirect3DVertexShader9 *shader;
1972     IDirect3DVertexDeclaration9 *decl;
1973     D3DCAPS9 caps;
1974     const DWORD shader_code[] = {
1975         0xfffe0101,                                     /* vs_1_1           */
1976         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1977         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1978         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1979         0x0000ffff                                      /* end              */
1980     };
1981     static const D3DVERTEXELEMENT9 decl_elements[] = {
1982         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1983         D3DDECL_END()
1984     };
1985     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1986      * then call Present. Then clear the color buffer to make sure it has some defined content
1987      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1988      * by the depth value.
1989      */
1990     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1991     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1992     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1993     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1994
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1996     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1998     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1999     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2000     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2002     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2003     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2004     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2005
2006     hr = IDirect3DDevice9_BeginScene(device);
2007     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2008     if(hr == D3D_OK)
2009     {
2010         /* Test the untransformed vertex path */
2011         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2012         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2013         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2014         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2015         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2016         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2017
2018         /* Test the transformed vertex path */
2019         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2020         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2021
2022         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2023         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2025         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2026         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2027         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2028
2029         hr = IDirect3DDevice9_EndScene(device);
2030         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2031     }
2032
2033     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2034     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2035
2036     /* Do not test the exact corner pixels, but go pretty close to them */
2037
2038     /* Clipped because z > 1.0 */
2039     color = getPixelColor(device, 28, 238);
2040     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2041     color = getPixelColor(device, 28, 241);
2042     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2043
2044     /* Not clipped, > z buffer clear value(0.75) */
2045     color = getPixelColor(device, 31, 238);
2046     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2047     color = getPixelColor(device, 31, 241);
2048     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2049     color = getPixelColor(device, 100, 238);
2050     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2051     color = getPixelColor(device, 100, 241);
2052     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2053
2054     /* Not clipped, < z buffer clear value */
2055     color = getPixelColor(device, 104, 238);
2056     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2057     color = getPixelColor(device, 104, 241);
2058     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2059     color = getPixelColor(device, 318, 238);
2060     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2061     color = getPixelColor(device, 318, 241);
2062     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2063
2064     /* Clipped because z < 0.0 */
2065     color = getPixelColor(device, 321, 238);
2066     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2067     color = getPixelColor(device, 321, 241);
2068     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2069
2070     /* Test the shader path */
2071     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2072     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2073         skip("Vertex shaders not supported\n");
2074         goto out;
2075     }
2076     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2077     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2078     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2079     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2080
2081     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2082
2083     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2084     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2085     IDirect3DDevice9_SetVertexShader(device, shader);
2086     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2087
2088     hr = IDirect3DDevice9_BeginScene(device);
2089     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2090     if(hr == D3D_OK)
2091     {
2092         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2093         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2094         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2096         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2097         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2098         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2099         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2101         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2102
2103         hr = IDirect3DDevice9_EndScene(device);
2104         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2105     }
2106
2107     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2108     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2109     IDirect3DDevice9_SetVertexShader(device, NULL);
2110     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2111
2112     IDirect3DVertexDeclaration9_Release(decl);
2113     IDirect3DVertexShader9_Release(shader);
2114
2115     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2116     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2117     /* Z < 1.0 */
2118     color = getPixelColor(device, 28, 238);
2119     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2120
2121     /* 1.0 < z < 0.75 */
2122     color = getPixelColor(device, 31, 238);
2123     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2124     color = getPixelColor(device, 100, 238);
2125     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2126
2127     /* 0.75 < z < 0.0 */
2128     color = getPixelColor(device, 104, 238);
2129     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2130     color = getPixelColor(device, 318, 238);
2131     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2132
2133     /* 0.0 < z */
2134     color = getPixelColor(device, 321, 238);
2135     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2136
2137     out:
2138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2141     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144 }
2145
2146 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2147 {
2148     D3DSURFACE_DESC desc;
2149     D3DLOCKED_RECT l;
2150     HRESULT hr;
2151     unsigned int x, y;
2152     DWORD *mem;
2153
2154     memset(&desc, 0, sizeof(desc));
2155     memset(&l, 0, sizeof(l));
2156     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2157     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2158     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2159     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2160     if(FAILED(hr)) return;
2161
2162     for(y = 0; y < desc.Height; y++)
2163     {
2164         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2165         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2166         {
2167             mem[x] = color;
2168         }
2169     }
2170     hr = IDirect3DSurface9_UnlockRect(surface);
2171     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2172 }
2173
2174 /* This tests a variety of possible StretchRect() situations */
2175 static void stretchrect_test(IDirect3DDevice9 *device)
2176 {
2177     HRESULT hr;
2178     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2179     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2180     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2181     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2182     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2183     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2184     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2185     IDirect3DSurface9 *orig_rt = NULL;
2186     DWORD color;
2187
2188     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2189     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2190     if(!orig_rt) {
2191         goto out;
2192     }
2193
2194     /* Create our temporary surfaces in system memory */
2195     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2196     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2197     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2198     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2199
2200     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2201     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2203     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2205     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2207
2208     /* Create render target surfaces */
2209     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2210     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2211     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2212     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2213     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2214     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2215
2216     /* Create render target textures */
2217     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2218     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2219     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2220     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2221     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2222     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2223     if (tex_rt32) {
2224         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2225         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2226     }
2227     if (tex_rt64) {
2228         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2229         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2230     }
2231     if (tex_rt_dest64) {
2232         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2233         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2234     }
2235
2236     /* Create regular textures in D3DPOOL_DEFAULT */
2237     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2238     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2239     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2240     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2241     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2242     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2243     if (tex32) {
2244         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2245         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2246     }
2247     if (tex64) {
2248         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2249         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2250     }
2251     if (tex_dest64) {
2252         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2253         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2254     }
2255
2256     /*********************************************************************
2257      * Tests for when the source parameter is an offscreen plain surface *
2258      *********************************************************************/
2259
2260     /* Fill the offscreen 64x64 surface with green */
2261     if (surf_offscreen64)
2262         fill_surface(surf_offscreen64, 0xff00ff00);
2263
2264     /* offscreenplain ==> offscreenplain, same size */
2265     if(surf_offscreen64 && surf_offscreen_dest64) {
2266         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2267         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2268
2269         if (hr == D3D_OK) {
2270             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2271             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2272         }
2273     }
2274
2275     /* offscreenplain ==> rendertarget texture, same size */
2276     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2277         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2278         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2279
2280         /* We can't lock rendertarget textures, so copy to our temp surface first */
2281         if (hr == D3D_OK) {
2282             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2283             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2284         }
2285
2286         if (hr == D3D_OK) {
2287             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2288             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2289         }
2290     }
2291
2292     /* offscreenplain ==> rendertarget surface, same size */
2293     if(surf_offscreen64 && surf_rt_dest64) {
2294         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2295         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2296
2297         if (hr == D3D_OK) {
2298             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2299             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2300         }
2301     }
2302
2303     /* offscreenplain ==> texture, same size (should fail) */
2304     if(surf_offscreen64 && surf_tex_dest64) {
2305         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2306         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2307     }
2308
2309     /* Fill the smaller offscreen surface with red */
2310     fill_surface(surf_offscreen32, 0xffff0000);
2311
2312     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2313     if(surf_offscreen32 && surf_offscreen64) {
2314         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2315         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2316     }
2317
2318     /* offscreenplain ==> rendertarget texture, scaling */
2319     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2320         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2321         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2322
2323         /* We can't lock rendertarget textures, so copy to our temp surface first */
2324         if (hr == D3D_OK) {
2325             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2326             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2327         }
2328
2329         if (hr == D3D_OK) {
2330             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2331             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2332         }
2333     }
2334
2335     /* offscreenplain ==> rendertarget surface, scaling */
2336     if(surf_offscreen32 && surf_rt_dest64) {
2337         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2338         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2339
2340         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2341         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2342     }
2343
2344     /* offscreenplain ==> texture, scaling (should fail) */
2345     if(surf_offscreen32 && surf_tex_dest64) {
2346         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2347         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2348     }
2349
2350     /************************************************************
2351      * Tests for when the source parameter is a regular texture *
2352      ************************************************************/
2353
2354     /* Fill the surface of the regular texture with blue */
2355     if (surf_tex64 && surf_temp64) {
2356         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2357         fill_surface(surf_temp64, 0xff0000ff);
2358         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2359         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2360     }
2361
2362     /* texture ==> offscreenplain, same size */
2363     if(surf_tex64 && surf_offscreen64) {
2364         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2365         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2366     }
2367
2368     /* texture ==> rendertarget texture, same size */
2369     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2370         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2371         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2372
2373         /* We can't lock rendertarget textures, so copy to our temp surface first */
2374         if (hr == D3D_OK) {
2375             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2376             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2377         }
2378
2379         if (hr == D3D_OK) {
2380             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2381             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2382         }
2383     }
2384
2385     /* texture ==> rendertarget surface, same size */
2386     if(surf_tex64 && surf_rt_dest64) {
2387         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2388         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2389
2390         if (hr == D3D_OK) {
2391             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2392             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2393         }
2394     }
2395
2396     /* texture ==> texture, same size (should fail) */
2397     if(surf_tex64 && surf_tex_dest64) {
2398         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2399         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2400     }
2401
2402     /* Fill the surface of the smaller regular texture with red */
2403     if (surf_tex32 && surf_temp32) {
2404         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2405         fill_surface(surf_temp32, 0xffff0000);
2406         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2407         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2408     }
2409
2410     /* texture ==> offscreenplain, scaling (should fail) */
2411     if(surf_tex32 && surf_offscreen64) {
2412         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2413         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2414     }
2415
2416     /* texture ==> rendertarget texture, scaling */
2417     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2418         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2419         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2420
2421         /* We can't lock rendertarget textures, so copy to our temp surface first */
2422         if (hr == D3D_OK) {
2423             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2424             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2425         }
2426
2427         if (hr == D3D_OK) {
2428             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2429             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2430         }
2431     }
2432
2433     /* texture ==> rendertarget surface, scaling */
2434     if(surf_tex32 && surf_rt_dest64) {
2435         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2436         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2437
2438         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2439         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2440     }
2441
2442     /* texture ==> texture, scaling (should fail) */
2443     if(surf_tex32 && surf_tex_dest64) {
2444         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2445         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2446     }
2447
2448     /*****************************************************************
2449      * Tests for when the source parameter is a rendertarget texture *
2450      *****************************************************************/
2451
2452     /* Fill the surface of the rendertarget texture with white */
2453     if (surf_tex_rt64 && surf_temp64) {
2454         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2455         fill_surface(surf_temp64, 0xffffffff);
2456         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2457         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2458     }
2459
2460     /* rendertarget texture ==> offscreenplain, same size */
2461     if(surf_tex_rt64 && surf_offscreen64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2463         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2464     }
2465
2466     /* rendertarget texture ==> rendertarget texture, same size */
2467     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2468         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2469         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2470
2471         /* We can't lock rendertarget textures, so copy to our temp surface first */
2472         if (hr == D3D_OK) {
2473             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2474             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2475         }
2476
2477         if (hr == D3D_OK) {
2478             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2479             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2480         }
2481     }
2482
2483     /* rendertarget texture ==> rendertarget surface, same size */
2484     if(surf_tex_rt64 && surf_rt_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2486         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2487
2488         if (hr == D3D_OK) {
2489             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2490             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2491         }
2492     }
2493
2494     /* rendertarget texture ==> texture, same size (should fail) */
2495     if(surf_tex_rt64 && surf_tex_dest64) {
2496         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2497         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2498     }
2499
2500     /* Fill the surface of the smaller rendertarget texture with red */
2501     if (surf_tex_rt32 && surf_temp32) {
2502         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2503         fill_surface(surf_temp32, 0xffff0000);
2504         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2505         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2506     }
2507
2508     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2509     if(surf_tex_rt32 && surf_offscreen64) {
2510         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2511         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2512     }
2513
2514     /* rendertarget texture ==> rendertarget texture, scaling */
2515     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2516         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2517         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2518
2519         /* We can't lock rendertarget textures, so copy to our temp surface first */
2520         if (hr == D3D_OK) {
2521             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2522             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2523         }
2524
2525         if (hr == D3D_OK) {
2526             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2527             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2528         }
2529     }
2530
2531     /* rendertarget texture ==> rendertarget surface, scaling */
2532     if(surf_tex_rt32 && surf_rt_dest64) {
2533         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2534         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2535
2536         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2537         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2538     }
2539
2540     /* rendertarget texture ==> texture, scaling (should fail) */
2541     if(surf_tex_rt32 && surf_tex_dest64) {
2542         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2543         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2544     }
2545
2546     /*****************************************************************
2547      * Tests for when the source parameter is a rendertarget surface *
2548      *****************************************************************/
2549
2550     /* Fill the surface of the rendertarget surface with black */
2551     if (surf_rt64)
2552         fill_surface(surf_rt64, 0xff000000);
2553
2554     /* rendertarget texture ==> offscreenplain, same size */
2555     if(surf_rt64 && surf_offscreen64) {
2556         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2557         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2558     }
2559
2560     /* rendertarget surface ==> rendertarget texture, same size */
2561     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2562         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2563         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2564
2565         /* We can't lock rendertarget textures, so copy to our temp surface first */
2566         if (hr == D3D_OK) {
2567             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2568             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2569         }
2570
2571         if (hr == D3D_OK) {
2572             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2573             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2574         }
2575     }
2576
2577     /* rendertarget surface ==> rendertarget surface, same size */
2578     if(surf_rt64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, 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 == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2585         }
2586     }
2587
2588     /* rendertarget surface ==> texture, same size (should fail) */
2589     if(surf_rt64 && surf_tex_dest64) {
2590         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2591         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2592     }
2593
2594     /* Fill the surface of the smaller rendertarget texture with red */
2595     if (surf_rt32)
2596         fill_surface(surf_rt32, 0xffff0000);
2597
2598     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2599     if(surf_rt32 && surf_offscreen64) {
2600         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2601         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2602     }
2603
2604     /* rendertarget surface ==> rendertarget texture, scaling */
2605     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2606         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2607         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2608
2609         /* We can't lock rendertarget textures, so copy to our temp surface first */
2610         if (hr == D3D_OK) {
2611             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2612             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2613         }
2614
2615         if (hr == D3D_OK) {
2616             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2617             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2618         }
2619     }
2620
2621     /* rendertarget surface ==> rendertarget surface, scaling */
2622     if(surf_rt32 && surf_rt_dest64) {
2623         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2624         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2625
2626         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2627         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2628     }
2629
2630     /* rendertarget surface ==> texture, scaling (should fail) */
2631     if(surf_rt32 && surf_tex_dest64) {
2632         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2633         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2634     }
2635
2636     /* TODO: Test when source and destination RECT parameters are given... */
2637     /* TODO: Test format conversions */
2638
2639
2640 out:
2641     /* Clean up */
2642     if (surf_rt32)
2643         IDirect3DSurface9_Release(surf_rt32);
2644     if (surf_rt64)
2645         IDirect3DSurface9_Release(surf_rt64);
2646     if (surf_rt_dest64)
2647         IDirect3DSurface9_Release(surf_rt_dest64);
2648     if (surf_temp32)
2649         IDirect3DSurface9_Release(surf_temp32);
2650     if (surf_temp64)
2651         IDirect3DSurface9_Release(surf_temp64);
2652     if (surf_offscreen32)
2653         IDirect3DSurface9_Release(surf_offscreen32);
2654     if (surf_offscreen64)
2655         IDirect3DSurface9_Release(surf_offscreen64);
2656     if (surf_offscreen_dest64)
2657         IDirect3DSurface9_Release(surf_offscreen_dest64);
2658
2659     if (tex_rt32) {
2660         if (surf_tex_rt32)
2661             IDirect3DSurface9_Release(surf_tex_rt32);
2662         IDirect3DTexture9_Release(tex_rt32);
2663     }
2664     if (tex_rt64) {
2665         if (surf_tex_rt64)
2666             IDirect3DSurface9_Release(surf_tex_rt64);
2667         IDirect3DTexture9_Release(tex_rt64);
2668     }
2669     if (tex_rt_dest64) {
2670         if (surf_tex_rt_dest64)
2671             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2672         IDirect3DTexture9_Release(tex_rt_dest64);
2673     }
2674     if (tex32) {
2675         if (surf_tex32)
2676             IDirect3DSurface9_Release(surf_tex32);
2677         IDirect3DTexture9_Release(tex32);
2678     }
2679     if (tex64) {
2680         if (surf_tex64)
2681             IDirect3DSurface9_Release(surf_tex64);
2682         IDirect3DTexture9_Release(tex64);
2683     }
2684     if (tex_dest64) {
2685         if (surf_tex_dest64)
2686             IDirect3DSurface9_Release(surf_tex_dest64);
2687         IDirect3DTexture9_Release(tex_dest64);
2688     }
2689
2690     if (orig_rt) {
2691         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2692         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2693         IDirect3DSurface9_Release(orig_rt);
2694     }
2695 }
2696
2697 static void maxmip_test(IDirect3DDevice9 *device)
2698 {
2699     IDirect3DTexture9 *texture = NULL;
2700     IDirect3DSurface9 *surface = NULL;
2701     HRESULT hr;
2702     DWORD color;
2703     const float quads[] = {
2704         -1.0,   -1.0,   0.0,    0.0,    0.0,
2705         -1.0,    0.0,   0.0,    0.0,    1.0,
2706          0.0,   -1.0,   0.0,    1.0,    0.0,
2707          0.0,    0.0,   0.0,    1.0,    1.0,
2708
2709          0.0,   -1.0,   0.0,    0.0,    0.0,
2710          0.0,    0.0,   0.0,    0.0,    1.0,
2711          1.0,   -1.0,   0.0,    1.0,    0.0,
2712          1.0,    0.0,   0.0,    1.0,    1.0,
2713
2714          0.0,    0.0,   0.0,    0.0,    0.0,
2715          0.0,    1.0,   0.0,    0.0,    1.0,
2716          1.0,    0.0,   0.0,    1.0,    0.0,
2717          1.0,    1.0,   0.0,    1.0,    1.0,
2718
2719         -1.0,    0.0,   0.0,    0.0,    0.0,
2720         -1.0,    1.0,   0.0,    0.0,    1.0,
2721          0.0,    0.0,   0.0,    1.0,    0.0,
2722          0.0,    1.0,   0.0,    1.0,    1.0,
2723     };
2724
2725     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2726     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2727
2728     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2729                                         &texture, NULL);
2730     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2731     if(!texture)
2732     {
2733         skip("Failed to create test texture\n");
2734         return;
2735     }
2736
2737     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2738     fill_surface(surface, 0xffff0000);
2739     IDirect3DSurface9_Release(surface);
2740     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2741     fill_surface(surface, 0xff00ff00);
2742     IDirect3DSurface9_Release(surface);
2743     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2744     fill_surface(surface, 0xff0000ff);
2745     IDirect3DSurface9_Release(surface);
2746
2747     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2748     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2749     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2750     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2751
2752     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2753     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2754
2755     hr = IDirect3DDevice9_BeginScene(device);
2756     if(SUCCEEDED(hr))
2757     {
2758         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2759         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2760         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2761         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2762
2763         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2764         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2766         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2767
2768         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2769         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2771         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2772
2773         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2774         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2775         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2776         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2777         hr = IDirect3DDevice9_EndScene(device);
2778     }
2779
2780     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2781     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2782     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2783     color = getPixelColor(device, 160, 360);
2784     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2785     color = getPixelColor(device, 160, 120);
2786     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2787     color = getPixelColor(device, 480, 120);
2788     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2789     color = getPixelColor(device, 480, 360);
2790     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2791
2792     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2793     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2794
2795     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2796     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2797
2798     hr = IDirect3DDevice9_BeginScene(device);
2799     if(SUCCEEDED(hr))
2800     {
2801         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2802         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2804         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2805
2806         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2807         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2809         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2810
2811         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2812         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2813         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2814         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2815
2816         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2817         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2819         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2820         hr = IDirect3DDevice9_EndScene(device);
2821     }
2822
2823     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2824     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2825     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2826     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2827
2828     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2829     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2830     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2831      * samples from the highest level in the texture(level 2)
2832      */
2833     color = getPixelColor(device, 160, 360);
2834     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2835     color = getPixelColor(device, 160, 120);
2836     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2837     color = getPixelColor(device, 480, 120);
2838     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2839     color = getPixelColor(device, 480, 360);
2840     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2841
2842     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2843     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2844     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2845     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2846     IDirect3DTexture9_Release(texture);
2847 }
2848
2849 static void release_buffer_test(IDirect3DDevice9 *device)
2850 {
2851     IDirect3DVertexBuffer9 *vb = NULL;
2852     IDirect3DIndexBuffer9 *ib = NULL;
2853     HRESULT hr;
2854     BYTE *data;
2855     LONG ref;
2856
2857     static const struct vertex quad[] = {
2858         {-1.0,      -1.0,       0.1,        0xffff0000},
2859         {-1.0,       1.0,       0.1,        0xffff0000},
2860         { 1.0,       1.0,       0.1,        0xffff0000},
2861
2862         {-1.0,      -1.0,       0.1,        0xff00ff00},
2863         {-1.0,       1.0,       0.1,        0xff00ff00},
2864         { 1.0,       1.0,       0.1,        0xff00ff00}
2865     };
2866     short indices[] = {3, 4, 5};
2867
2868     /* Index and vertex buffers should always be creatable */
2869     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2870                                               D3DPOOL_MANAGED, &vb, NULL);
2871     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2872     if(!vb) {
2873         skip("Failed to create a vertex buffer\n");
2874         return;
2875     }
2876     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2877     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2878     if(!ib) {
2879         skip("Failed to create an index buffer\n");
2880         return;
2881     }
2882
2883     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2884     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2885     memcpy(data, quad, sizeof(quad));
2886     hr = IDirect3DVertexBuffer9_Unlock(vb);
2887     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2888
2889     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2890     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2891     memcpy(data, indices, sizeof(indices));
2892     hr = IDirect3DIndexBuffer9_Unlock(ib);
2893     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2894
2895     hr = IDirect3DDevice9_SetIndices(device, ib);
2896     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2897     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2898     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2899     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2900     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2901
2902     /* Now destroy the bound index buffer and draw again */
2903     ref = IDirect3DIndexBuffer9_Release(ib);
2904     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2905
2906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2907     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2908
2909     hr = IDirect3DDevice9_BeginScene(device);
2910     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2911     if(SUCCEEDED(hr))
2912     {
2913         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2914          * making assumptions about the indices or vertices
2915          */
2916         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2917         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2918         hr = IDirect3DDevice9_EndScene(device);
2919         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2920     }
2921
2922     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2923     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2924
2925     hr = IDirect3DDevice9_SetIndices(device, NULL);
2926     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2927     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2928     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2929
2930     /* Index buffer was already destroyed as part of the test */
2931     IDirect3DVertexBuffer9_Release(vb);
2932 }
2933
2934 static void float_texture_test(IDirect3DDevice9 *device)
2935 {
2936     IDirect3D9 *d3d = NULL;
2937     HRESULT hr;
2938     IDirect3DTexture9 *texture = NULL;
2939     D3DLOCKED_RECT lr;
2940     float *data;
2941     DWORD color;
2942     float quad[] = {
2943         -1.0,      -1.0,       0.1,     0.0,    0.0,
2944         -1.0,       1.0,       0.1,     0.0,    1.0,
2945          1.0,      -1.0,       0.1,     1.0,    0.0,
2946          1.0,       1.0,       0.1,     1.0,    1.0,
2947     };
2948
2949     memset(&lr, 0, sizeof(lr));
2950     IDirect3DDevice9_GetDirect3D(device, &d3d);
2951     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2952                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2953         skip("D3DFMT_R32F textures not supported\n");
2954         goto out;
2955     }
2956
2957     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2958                                         D3DPOOL_MANAGED, &texture, NULL);
2959     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2960     if(!texture) {
2961         skip("Failed to create R32F texture\n");
2962         goto out;
2963     }
2964
2965     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2966     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2967     data = lr.pBits;
2968     *data = 0.0;
2969     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2970     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2971
2972     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2973     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2974
2975     hr = IDirect3DDevice9_BeginScene(device);
2976     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2977     if(SUCCEEDED(hr))
2978     {
2979         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2980         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2981
2982         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2983         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2984
2985         hr = IDirect3DDevice9_EndScene(device);
2986         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2987     }
2988     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2989     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2990
2991     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2992     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2993
2994     color = getPixelColor(device, 240, 320);
2995     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2996
2997 out:
2998     if(texture) IDirect3DTexture9_Release(texture);
2999     IDirect3D9_Release(d3d);
3000 }
3001
3002 static void g16r16_texture_test(IDirect3DDevice9 *device)
3003 {
3004     IDirect3D9 *d3d = NULL;
3005     HRESULT hr;
3006     IDirect3DTexture9 *texture = NULL;
3007     D3DLOCKED_RECT lr;
3008     DWORD *data;
3009     DWORD color;
3010     float quad[] = {
3011        -1.0,      -1.0,       0.1,     0.0,    0.0,
3012        -1.0,       1.0,       0.1,     0.0,    1.0,
3013         1.0,      -1.0,       0.1,     1.0,    0.0,
3014         1.0,       1.0,       0.1,     1.0,    1.0,
3015     };
3016
3017     memset(&lr, 0, sizeof(lr));
3018     IDirect3DDevice9_GetDirect3D(device, &d3d);
3019     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3020        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3021            skip("D3DFMT_G16R16 textures not supported\n");
3022            goto out;
3023     }
3024
3025     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3026                                         D3DPOOL_MANAGED, &texture, NULL);
3027     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3028     if(!texture) {
3029         skip("Failed to create D3DFMT_G16R16 texture\n");
3030         goto out;
3031     }
3032
3033     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3034     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3035     data = lr.pBits;
3036     *data = 0x0f00f000;
3037     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3038     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3039
3040     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3041     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3042
3043     hr = IDirect3DDevice9_BeginScene(device);
3044     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3045     if(SUCCEEDED(hr))
3046     {
3047         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3048         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3049
3050         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3051         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3052
3053         hr = IDirect3DDevice9_EndScene(device);
3054         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3055     }
3056     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3057     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3058
3059     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3060     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3061
3062     color = getPixelColor(device, 240, 320);
3063     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3064        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3065
3066 out:
3067     if(texture) IDirect3DTexture9_Release(texture);
3068     IDirect3D9_Release(d3d);
3069 }
3070
3071 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3072 {
3073     HRESULT hr;
3074     IDirect3D9 *d3d;
3075     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3076     D3DCAPS9 caps;
3077     IDirect3DTexture9 *texture = NULL;
3078     IDirect3DVolumeTexture9 *volume = NULL;
3079     unsigned int x, y, z;
3080     D3DLOCKED_RECT lr;
3081     D3DLOCKED_BOX lb;
3082     DWORD color;
3083     UINT w, h;
3084     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3085     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3086                            0.0, 1.0, 0.0, 0.0,
3087                            0.0, 0.0, 1.0, 0.0,
3088                            0.0, 0.0, 0.0, 1.0};
3089     static const D3DVERTEXELEMENT9 decl_elements[] = {
3090         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3091         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3092         D3DDECL_END()
3093     };
3094     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3095         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3096         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3097         D3DDECL_END()
3098     };
3099     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3100         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3101         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3102         D3DDECL_END()
3103     };
3104     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3105                                                  0x00, 0xff, 0x00, 0x00,
3106                                                  0x00, 0x00, 0x00, 0x00,
3107                                                  0x00, 0x00, 0x00, 0x00};
3108
3109     memset(&lr, 0, sizeof(lr));
3110     memset(&lb, 0, sizeof(lb));
3111     IDirect3DDevice9_GetDirect3D(device, &d3d);
3112     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3113                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3114         fmt = D3DFMT_A16B16G16R16;
3115     }
3116     IDirect3D9_Release(d3d);
3117
3118     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3119     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3120     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3121     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3122     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3123     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3124     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3125     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3126     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3127     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3128     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3129     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3130     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3131     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3132     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3133     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3134     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3135     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3136     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3137     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3140     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3141     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3142
3143     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3144     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3145     w = min(1024, caps.MaxTextureWidth);
3146     h = min(1024, caps.MaxTextureHeight);
3147     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3148                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3149     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3150     if(!texture) {
3151         skip("Failed to create the test texture\n");
3152         return;
3153     }
3154
3155     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3156      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3157      * 1.0 in red and green for the x and y coords
3158      */
3159     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3160     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3161     for(y = 0; y < h; y++) {
3162         for(x = 0; x < w; x++) {
3163             double r_f = (double) y / (double) h;
3164             double g_f = (double) x / (double) w;
3165             if(fmt == D3DFMT_A16B16G16R16) {
3166                 unsigned short r, g;
3167                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3168                 r = (unsigned short) (r_f * 65536.0);
3169                 g = (unsigned short) (g_f * 65536.0);
3170                 dst[0] = r;
3171                 dst[1] = g;
3172                 dst[2] = 0;
3173                 dst[3] = 65535;
3174             } else {
3175                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3176                 unsigned char r = (unsigned char) (r_f * 255.0);
3177                 unsigned char g = (unsigned char) (g_f * 255.0);
3178                 dst[0] = 0;
3179                 dst[1] = g;
3180                 dst[2] = r;
3181                 dst[3] = 255;
3182             }
3183         }
3184     }
3185     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3186     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3187     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3188     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3189
3190     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3191     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3192     hr = IDirect3DDevice9_BeginScene(device);
3193     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3194     if(SUCCEEDED(hr))
3195     {
3196         float quad1[] = {
3197             -1.0,      -1.0,       0.1,     1.0,    1.0,
3198             -1.0,       0.0,       0.1,     1.0,    1.0,
3199              0.0,      -1.0,       0.1,     1.0,    1.0,
3200              0.0,       0.0,       0.1,     1.0,    1.0,
3201         };
3202         float quad2[] = {
3203             -1.0,       0.0,       0.1,     1.0,    1.0,
3204             -1.0,       1.0,       0.1,     1.0,    1.0,
3205              0.0,       0.0,       0.1,     1.0,    1.0,
3206              0.0,       1.0,       0.1,     1.0,    1.0,
3207         };
3208         float quad3[] = {
3209              0.0,       0.0,       0.1,     0.5,    0.5,
3210              0.0,       1.0,       0.1,     0.5,    0.5,
3211              1.0,       0.0,       0.1,     0.5,    0.5,
3212              1.0,       1.0,       0.1,     0.5,    0.5,
3213         };
3214         float quad4[] = {
3215              320,       480,       0.1,     1.0,    0.0,    1.0,
3216              320,       240,       0.1,     1.0,    0.0,    1.0,
3217              640,       480,       0.1,     1.0,    0.0,    1.0,
3218              640,       240,       0.1,     1.0,    0.0,    1.0,
3219         };
3220         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3221                           0.0, 0.0, 0.0, 0.0,
3222                           0.0, 0.0, 0.0, 0.0,
3223                           0.0, 0.0, 0.0, 0.0};
3224
3225         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3226         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3227         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3228         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3229         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3230
3231         /* What happens with transforms enabled? */
3232         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3233         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3235         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3236
3237         /* What happens if 4 coords are used, but only 2 given ?*/
3238         mat[8] = 1.0;
3239         mat[13] = 1.0;
3240         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3241         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3242         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3243         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3245         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3246
3247         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3248          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3249          * due to the coords in the vertices. (turns out red, indeed)
3250          */
3251         memset(mat, 0, sizeof(mat));
3252         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3253         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3254         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3255         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3256         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3257         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3258         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3259         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3260
3261         hr = IDirect3DDevice9_EndScene(device);
3262         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3263     }
3264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3265     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3266     color = getPixelColor(device, 160, 360);
3267     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3268     color = getPixelColor(device, 160, 120);
3269     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3270     color = getPixelColor(device, 480, 120);
3271     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3272     color = getPixelColor(device, 480, 360);
3273     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3274
3275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3276     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3277
3278     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3279     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3280     hr = IDirect3DDevice9_BeginScene(device);
3281     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3282     if(SUCCEEDED(hr))
3283     {
3284         float quad1[] = {
3285             -1.0,      -1.0,       0.1,     0.8,    0.2,
3286             -1.0,       0.0,       0.1,     0.8,    0.2,
3287              0.0,      -1.0,       0.1,     0.8,    0.2,
3288              0.0,       0.0,       0.1,     0.8,    0.2,
3289         };
3290         float quad2[] = {
3291             -1.0,       0.0,       0.1,     0.5,    1.0,
3292             -1.0,       1.0,       0.1,     0.5,    1.0,
3293              0.0,       0.0,       0.1,     0.5,    1.0,
3294              0.0,       1.0,       0.1,     0.5,    1.0,
3295         };
3296         float quad3[] = {
3297              0.0,       0.0,       0.1,     0.5,    1.0,
3298              0.0,       1.0,       0.1,     0.5,    1.0,
3299              1.0,       0.0,       0.1,     0.5,    1.0,
3300              1.0,       1.0,       0.1,     0.5,    1.0,
3301         };
3302         float quad4[] = {
3303              0.0,      -1.0,       0.1,     0.8,    0.2,
3304              0.0,       0.0,       0.1,     0.8,    0.2,
3305              1.0,      -1.0,       0.1,     0.8,    0.2,
3306              1.0,       0.0,       0.1,     0.8,    0.2,
3307         };
3308         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3309                           0.0, 0.0, 0.0, 0.0,
3310                           0.0, 1.0, 0.0, 0.0,
3311                           0.0, 0.0, 0.0, 0.0};
3312
3313         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3314          */
3315         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3316         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3317         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3318         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3319
3320         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3321         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3322
3323         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3324          * it behaves like COUNT2 because normal textures require 2 coords
3325          */
3326         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3327         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3328         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3329         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3330
3331         /* Just to be sure, the same as quad2 above */
3332         memset(mat, 0, sizeof(mat));
3333         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3334         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3335         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3336         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3337         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3338         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3339
3340         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3341          * used? And what happens to the first?
3342          */
3343         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3344         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3346         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3347
3348         hr = IDirect3DDevice9_EndScene(device);
3349         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3350     }
3351     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3352     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3353     color = getPixelColor(device, 160, 360);
3354     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3355     color = getPixelColor(device, 160, 120);
3356     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3357     color = getPixelColor(device, 480, 120);
3358     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3359        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3360     color = getPixelColor(device, 480, 360);
3361     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3362        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3363
3364     IDirect3DTexture9_Release(texture);
3365
3366     /* Test projected textures, without any fancy matrices */
3367     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3368     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3369     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3370     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3371     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3372     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3373     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3374     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3375
3376     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3377     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3378     for(x = 0; x < 4; x++) {
3379         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3380     }
3381     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3383     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3384     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3385
3386     hr = IDirect3DDevice9_BeginScene(device);
3387     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3388     if(SUCCEEDED(hr))
3389     {
3390         const float proj_quads[] = {
3391            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3392             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3393            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3394             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3395            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3396             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3397            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3398             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3399         };
3400
3401         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3402         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3404         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3405
3406         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3407         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3409         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3410
3411         hr = IDirect3DDevice9_EndScene(device);
3412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3413     }
3414
3415     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3416     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3417     IDirect3DTexture9_Release(texture);
3418
3419     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3420     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3421     color = getPixelColor(device, 158, 118);
3422     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3423     color = getPixelColor(device, 162, 118);
3424     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3425     color = getPixelColor(device, 158, 122);
3426     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3427     color = getPixelColor(device, 162, 122);
3428     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3429
3430     color = getPixelColor(device, 158, 178);
3431     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3432     color = getPixelColor(device, 162, 178);
3433     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3434     color = getPixelColor(device, 158, 182);
3435     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3436     color = getPixelColor(device, 162, 182);
3437     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3438
3439     color = getPixelColor(device, 318, 118);
3440     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3441     color = getPixelColor(device, 322, 118);
3442     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3443     color = getPixelColor(device, 318, 122);
3444     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3445     color = getPixelColor(device, 322, 122);
3446     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3447
3448     color = getPixelColor(device, 318, 178);
3449     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3450     color = getPixelColor(device, 322, 178);
3451     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3452     color = getPixelColor(device, 318, 182);
3453     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3454     color = getPixelColor(device, 322, 182);
3455     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3456
3457     color = getPixelColor(device, 238, 298);
3458     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3459     color = getPixelColor(device, 242, 298);
3460     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3461     color = getPixelColor(device, 238, 302);
3462     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3463     color = getPixelColor(device, 242, 302);
3464     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3465
3466     color = getPixelColor(device, 238, 388);
3467     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3468     color = getPixelColor(device, 242, 388);
3469     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3470     color = getPixelColor(device, 238, 392);
3471     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3472     color = getPixelColor(device, 242, 392);
3473     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3474
3475     color = getPixelColor(device, 478, 298);
3476     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3477     color = getPixelColor(device, 482, 298);
3478     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3479     color = getPixelColor(device, 478, 302);
3480     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3481     color = getPixelColor(device, 482, 302);
3482     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3483
3484     color = getPixelColor(device, 478, 388);
3485     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3486     color = getPixelColor(device, 482, 388);
3487     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3488     color = getPixelColor(device, 478, 392);
3489     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3490     color = getPixelColor(device, 482, 392);
3491     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3492
3493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3495     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3496      * Thus watch out if sampling from texels between 0 and 1.
3497      */
3498     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3499     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3500        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3501     if(!volume) {
3502         skip("Failed to create a volume texture\n");
3503         goto out;
3504     }
3505
3506     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3507     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3508     for(z = 0; z < 32; z++) {
3509         for(y = 0; y < 32; y++) {
3510             for(x = 0; x < 32; x++) {
3511                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3512                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3513                 float r_f = (float) x / 31.0;
3514                 float g_f = (float) y / 31.0;
3515                 float b_f = (float) z / 31.0;
3516
3517                 if(fmt == D3DFMT_A16B16G16R16) {
3518                     unsigned short *mem_s = mem;
3519                     mem_s[0]  = r_f * 65535.0;
3520                     mem_s[1]  = g_f * 65535.0;
3521                     mem_s[2]  = b_f * 65535.0;
3522                     mem_s[3]  = 65535;
3523                 } else {
3524                     unsigned char *mem_c = mem;
3525                     mem_c[0]  = b_f * 255.0;
3526                     mem_c[1]  = g_f * 255.0;
3527                     mem_c[2]  = r_f * 255.0;
3528                     mem_c[3]  = 255;
3529                 }
3530             }
3531         }
3532     }
3533     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3534     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3535
3536     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3537     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3538
3539     hr = IDirect3DDevice9_BeginScene(device);
3540     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3541     if(SUCCEEDED(hr))
3542     {
3543         float quad1[] = {
3544             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3545             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3546              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3547              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3548         };
3549         float quad2[] = {
3550             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3551             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3552              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3553              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3554         };
3555         float quad3[] = {
3556              0.0,       0.0,       0.1,     0.0,    0.0,
3557              0.0,       1.0,       0.1,     0.0,    0.0,
3558              1.0,       0.0,       0.1,     0.0,    0.0,
3559              1.0,       1.0,       0.1,     0.0,    0.0
3560         };
3561         float quad4[] = {
3562              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3563              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3564              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3565              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3566         };
3567         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3568                          0.0, 0.0, 1.0, 0.0,
3569                          0.0, 1.0, 0.0, 0.0,
3570                          0.0, 0.0, 0.0, 1.0};
3571         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3572         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3573
3574         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3575          * values
3576          */
3577         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3578         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3579         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3580         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3581         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3582         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3583
3584         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3585          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3586          * otherwise the w will be missing(blue).
3587          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3588          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3589          */
3590         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3591         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3592         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3593         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3594
3595         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3596         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3599         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3600         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3601         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3603         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3604
3605         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3606          * disable. ATI extends it up to the amount of values needed for the volume texture
3607          */
3608         memset(mat, 0, sizeof(mat));
3609         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3610         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3611         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3612         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3613         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3614         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3615         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3616         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3617
3618         hr = IDirect3DDevice9_EndScene(device);
3619         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3620     }
3621     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3622     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3623
3624     color = getPixelColor(device, 160, 360);
3625     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3626     color = getPixelColor(device, 160, 120);
3627     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3628        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3629     color = getPixelColor(device, 480, 120);
3630     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3631     color = getPixelColor(device, 480, 360);
3632     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3633
3634     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3635     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3636     hr = IDirect3DDevice9_BeginScene(device);
3637     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3638     if(SUCCEEDED(hr))
3639     {
3640         float quad1[] = {
3641             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3642             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3643              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3644              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3645         };
3646         float quad2[] = {
3647             -1.0,       0.0,       0.1,
3648             -1.0,       1.0,       0.1,
3649              0.0,       0.0,       0.1,
3650              0.0,       1.0,       0.1,
3651         };
3652         float quad3[] = {
3653              0.0,       0.0,       0.1,     1.0,
3654              0.0,       1.0,       0.1,     1.0,
3655              1.0,       0.0,       0.1,     1.0,
3656              1.0,       1.0,       0.1,     1.0
3657         };
3658         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3659                            0.0, 0.0, 0.0, 0.0,
3660                            0.0, 0.0, 0.0, 0.0,
3661                            0.0, 1.0, 0.0, 0.0};
3662         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3663                            1.0, 0.0, 0.0, 0.0,
3664                            0.0, 1.0, 0.0, 0.0,
3665                            0.0, 0.0, 1.0, 0.0};
3666         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3667         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3668
3669         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3670          */
3671         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3672         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3673         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3674         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3675         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3676         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3677
3678         /* None passed */
3679         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3680         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3682         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3683         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3684         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3685
3686         /* 4 used, 1 passed */
3687         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3688         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3689         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3690         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3691         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3692         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3693
3694         hr = IDirect3DDevice9_EndScene(device);
3695         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3696     }
3697     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3698     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3699     color = getPixelColor(device, 160, 360);
3700     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3701     color = getPixelColor(device, 160, 120);
3702     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3703     color = getPixelColor(device, 480, 120);
3704     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3705     /* Quad4: unused */
3706
3707     IDirect3DVolumeTexture9_Release(volume);
3708
3709     out:
3710     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3711     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3712     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3713     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3714     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3715     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3716     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3717     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3718     IDirect3DVertexDeclaration9_Release(decl);
3719     IDirect3DVertexDeclaration9_Release(decl2);
3720     IDirect3DVertexDeclaration9_Release(decl3);
3721 }
3722
3723 static void texdepth_test(IDirect3DDevice9 *device)
3724 {
3725     IDirect3DPixelShader9 *shader;
3726     HRESULT hr;
3727     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3728     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3729     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3730     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3731     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3732     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3733     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3734     DWORD shader_code[] = {
3735         0xffff0104,                                                                 /* ps_1_4               */
3736         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3737         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3738         0x0000fffd,                                                                 /* phase                */
3739         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3740         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3741         0x0000ffff                                                                  /* end                  */
3742     };
3743     DWORD color;
3744     float vertex[] = {
3745        -1.0,   -1.0,    0.0,
3746         1.0,   -1.0,    1.0,
3747        -1.0,    1.0,    0.0,
3748         1.0,    1.0,    1.0
3749     };
3750
3751     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3752     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3753
3754     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3755     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3757     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3759     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3760     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3761     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3762     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3763
3764     /* Fill the depth buffer with a gradient */
3765     hr = IDirect3DDevice9_BeginScene(device);
3766     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3767     if(SUCCEEDED(hr))
3768     {
3769         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3770         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3771         hr = IDirect3DDevice9_EndScene(device);
3772         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3773     }
3774
3775     /* Now perform the actual tests. Same geometry, but with the shader */
3776     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3778     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3779     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3780     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3781     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3782
3783     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3784     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3785     hr = IDirect3DDevice9_BeginScene(device);
3786     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3787     if(SUCCEEDED(hr))
3788     {
3789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3790         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3791
3792         hr = IDirect3DDevice9_EndScene(device);
3793         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3794     }
3795
3796     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3797     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3798     color = getPixelColor(device, 158, 240);
3799     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3800     color = getPixelColor(device, 162, 240);
3801     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3802
3803     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3804
3805     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3806     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3807     hr = IDirect3DDevice9_BeginScene(device);
3808     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3809     if(SUCCEEDED(hr))
3810     {
3811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3812         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3813
3814         hr = IDirect3DDevice9_EndScene(device);
3815         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3816     }
3817
3818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3819     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3820     color = getPixelColor(device, 318, 240);
3821     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3822     color = getPixelColor(device, 322, 240);
3823     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3824
3825     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3826
3827     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3828     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3829     hr = IDirect3DDevice9_BeginScene(device);
3830     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3831     if(SUCCEEDED(hr))
3832     {
3833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3834         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3835
3836         hr = IDirect3DDevice9_EndScene(device);
3837         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3838     }
3839     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3840     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3841
3842     color = getPixelColor(device, 1, 240);
3843     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3844
3845     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3846
3847     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3848     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3849     hr = IDirect3DDevice9_BeginScene(device);
3850     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3851     if(SUCCEEDED(hr))
3852     {
3853         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3854         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3855
3856         hr = IDirect3DDevice9_EndScene(device);
3857         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3858     }
3859     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3860     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3861     color = getPixelColor(device, 318, 240);
3862     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3863     color = getPixelColor(device, 322, 240);
3864     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3865
3866     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3867
3868     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3869     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3870     hr = IDirect3DDevice9_BeginScene(device);
3871     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3872     if(SUCCEEDED(hr))
3873     {
3874         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3875         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3876
3877         hr = IDirect3DDevice9_EndScene(device);
3878         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3879     }
3880     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3881     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3882
3883     color = getPixelColor(device, 1, 240);
3884     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3885
3886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3887
3888     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3890     hr = IDirect3DDevice9_BeginScene(device);
3891     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3892     if(SUCCEEDED(hr))
3893     {
3894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3895         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3896
3897         hr = IDirect3DDevice9_EndScene(device);
3898         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3899     }
3900     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3901     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3902
3903     color = getPixelColor(device, 638, 240);
3904     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3905
3906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3907
3908     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3909     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3910     hr = IDirect3DDevice9_BeginScene(device);
3911     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3912     if(SUCCEEDED(hr))
3913     {
3914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3915         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3916
3917         hr = IDirect3DDevice9_EndScene(device);
3918         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3919     }
3920     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3921     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3922
3923     color = getPixelColor(device, 638, 240);
3924     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3925
3926     /* Cleanup */
3927     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3928     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3929     IDirect3DPixelShader9_Release(shader);
3930
3931     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3933     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3934     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3935 }
3936
3937 static void texkill_test(IDirect3DDevice9 *device)
3938 {
3939     IDirect3DPixelShader9 *shader;
3940     HRESULT hr;
3941     DWORD color;
3942
3943     const float vertex[] = {
3944     /*                          bottom  top    right    left */
3945         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3946          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3947         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3948          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3949     };
3950
3951     DWORD shader_code_11[] = {
3952     0xffff0101,                                                             /* ps_1_1                     */
3953     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3954     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3955     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3956     0x0000ffff                                                              /* end                        */
3957     };
3958     DWORD shader_code_20[] = {
3959     0xffff0200,                                                             /* ps_2_0                     */
3960     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3961     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3962     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3963     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3964     0x0000ffff                                                              /* end                        */
3965     };
3966
3967     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3968     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3969     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3970     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3971
3972     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3973     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3974     hr = IDirect3DDevice9_BeginScene(device);
3975     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3976     if(SUCCEEDED(hr))
3977     {
3978         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3979         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3980         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3981         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3982         hr = IDirect3DDevice9_EndScene(device);
3983         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3984     }
3985     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3986     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3987     color = getPixelColor(device, 63, 46);
3988     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3989     color = getPixelColor(device, 66, 46);
3990     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3991     color = getPixelColor(device, 63, 49);
3992     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3993     color = getPixelColor(device, 66, 49);
3994     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3995
3996     color = getPixelColor(device, 578, 46);
3997     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3998     color = getPixelColor(device, 575, 46);
3999     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4000     color = getPixelColor(device, 578, 49);
4001     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4002     color = getPixelColor(device, 575, 49);
4003     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4004
4005     color = getPixelColor(device, 63, 430);
4006     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4007     color = getPixelColor(device, 63, 433);
4008     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4009     color = getPixelColor(device, 66, 433);
4010     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4011     color = getPixelColor(device, 66, 430);
4012     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4013
4014     color = getPixelColor(device, 578, 430);
4015     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4016     color = getPixelColor(device, 578, 433);
4017     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4018     color = getPixelColor(device, 575, 433);
4019     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4020     color = getPixelColor(device, 575, 430);
4021     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4022
4023     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4024     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4025     IDirect3DPixelShader9_Release(shader);
4026
4027     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4028     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4029     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4030     if(FAILED(hr)) {
4031         skip("Failed to create 2.0 test shader, most likely not supported\n");
4032         return;
4033     }
4034
4035     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4036     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4037     hr = IDirect3DDevice9_BeginScene(device);
4038     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4039     if(SUCCEEDED(hr))
4040     {
4041         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4042         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4043         hr = IDirect3DDevice9_EndScene(device);
4044         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4045     }
4046     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4047
4048     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4049     color = getPixelColor(device, 63, 46);
4050     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4051     color = getPixelColor(device, 66, 46);
4052     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4053     color = getPixelColor(device, 63, 49);
4054     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4055     color = getPixelColor(device, 66, 49);
4056     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4057
4058     color = getPixelColor(device, 578, 46);
4059     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4060     color = getPixelColor(device, 575, 46);
4061     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4062     color = getPixelColor(device, 578, 49);
4063     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4064     color = getPixelColor(device, 575, 49);
4065     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4066
4067     color = getPixelColor(device, 63, 430);
4068     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4069     color = getPixelColor(device, 63, 433);
4070     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4071     color = getPixelColor(device, 66, 433);
4072     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4073     color = getPixelColor(device, 66, 430);
4074     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4075
4076     color = getPixelColor(device, 578, 430);
4077     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4078     color = getPixelColor(device, 578, 433);
4079     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4080     color = getPixelColor(device, 575, 433);
4081     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4082     color = getPixelColor(device, 575, 430);
4083     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4084
4085     /* Cleanup */
4086     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4087     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4088     IDirect3DPixelShader9_Release(shader);
4089 }
4090
4091 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4092 {
4093     IDirect3D9 *d3d9;
4094     HRESULT hr;
4095     IDirect3DTexture9 *texture;
4096     IDirect3DPixelShader9 *shader;
4097     IDirect3DPixelShader9 *shader2;
4098     D3DLOCKED_RECT lr;
4099     DWORD color;
4100     DWORD shader_code[] = {
4101         0xffff0101,                             /* ps_1_1       */
4102         0x00000042, 0xb00f0000,                 /* tex t0       */
4103         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4104         0x0000ffff                              /* end          */
4105     };
4106     DWORD shader_code2[] = {
4107         0xffff0101,                             /* ps_1_1       */
4108         0x00000042, 0xb00f0000,                 /* tex t0       */
4109         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4110         0x0000ffff                              /* end          */
4111     };
4112
4113     float quad[] = {
4114        -1.0,   -1.0,   0.1,     0.5,    0.5,
4115         1.0,   -1.0,   0.1,     0.5,    0.5,
4116        -1.0,    1.0,   0.1,     0.5,    0.5,
4117         1.0,    1.0,   0.1,     0.5,    0.5,
4118     };
4119
4120     memset(&lr, 0, sizeof(lr));
4121     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4122     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4123                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4124     IDirect3D9_Release(d3d9);
4125     if(FAILED(hr)) {
4126         skip("No D3DFMT_X8L8V8U8 support\n");
4127     };
4128
4129     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4130     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4131
4132     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4133     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4134     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4135     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4136     *((DWORD *) lr.pBits) = 0x11ca3141;
4137     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4138     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4139
4140     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4141     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4142     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4143     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4144
4145     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4147     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4149     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4151
4152     hr = IDirect3DDevice9_BeginScene(device);
4153     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4154     if(SUCCEEDED(hr))
4155     {
4156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4157         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4158
4159         hr = IDirect3DDevice9_EndScene(device);
4160         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4161     }
4162     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4163     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4164     color = getPixelColor(device, 578, 430);
4165     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4166        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4167
4168     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4169     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4170     hr = IDirect3DDevice9_BeginScene(device);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4172     if(SUCCEEDED(hr))
4173     {
4174         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4175         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4176
4177         hr = IDirect3DDevice9_EndScene(device);
4178         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4179     }
4180     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4181     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4182     color = getPixelColor(device, 578, 430);
4183     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4184
4185     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4186     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4187     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4188     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4189     IDirect3DPixelShader9_Release(shader);
4190     IDirect3DPixelShader9_Release(shader2);
4191     IDirect3DTexture9_Release(texture);
4192 }
4193
4194 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4195 {
4196     HRESULT hr;
4197     IDirect3D9 *d3d;
4198     IDirect3DTexture9 *texture = NULL;
4199     IDirect3DSurface9 *surface;
4200     DWORD color;
4201     const RECT r1 = {256, 256, 512, 512};
4202     const RECT r2 = {512, 256, 768, 512};
4203     const RECT r3 = {256, 512, 512, 768};
4204     const RECT r4 = {512, 512, 768, 768};
4205     unsigned int x, y;
4206     D3DLOCKED_RECT lr;
4207     memset(&lr, 0, sizeof(lr));
4208
4209     IDirect3DDevice9_GetDirect3D(device, &d3d);
4210     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4211        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4212         skip("No autogenmipmap support\n");
4213         IDirect3D9_Release(d3d);
4214         return;
4215     }
4216     IDirect3D9_Release(d3d);
4217
4218     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4219     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4220
4221     /* Make the mipmap big, so that a smaller mipmap is used
4222      */
4223     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4224                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4225     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4226
4227     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4228     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4229     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4230     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4231     for(y = 0; y < 1024; y++) {
4232         for(x = 0; x < 1024; x++) {
4233             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4234             POINT pt;
4235
4236             pt.x = x;
4237             pt.y = y;
4238             if(PtInRect(&r1, pt)) {
4239                 *dst = 0xffff0000;
4240             } else if(PtInRect(&r2, pt)) {
4241                 *dst = 0xff00ff00;
4242             } else if(PtInRect(&r3, pt)) {
4243                 *dst = 0xff0000ff;
4244             } else if(PtInRect(&r4, pt)) {
4245                 *dst = 0xff000000;
4246             } else {
4247                 *dst = 0xffffffff;
4248             }
4249         }
4250     }
4251     hr = IDirect3DSurface9_UnlockRect(surface);
4252     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4253     IDirect3DSurface9_Release(surface);
4254
4255     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4257     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4258     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4259
4260     hr = IDirect3DDevice9_BeginScene(device);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4262     if(SUCCEEDED(hr)) {
4263         const float quad[] =  {
4264            -0.5,   -0.5,    0.1,    0.0,    0.0,
4265            -0.5,    0.5,    0.1,    0.0,    1.0,
4266             0.5,   -0.5,    0.1,    1.0,    0.0,
4267             0.5,    0.5,    0.1,    1.0,    1.0
4268         };
4269
4270         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4271         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4274         hr = IDirect3DDevice9_EndScene(device);
4275         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4276     }
4277     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4278     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4279     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4280     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4281     IDirect3DTexture9_Release(texture);
4282
4283     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4284     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4285     color = getPixelColor(device, 200, 200);
4286     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4287     color = getPixelColor(device, 280, 200);
4288     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4289     color = getPixelColor(device, 360, 200);
4290     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4291     color = getPixelColor(device, 440, 200);
4292     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4293     color = getPixelColor(device, 200, 270);
4294     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4295     color = getPixelColor(device, 280, 270);
4296     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4297     color = getPixelColor(device, 360, 270);
4298     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4299     color = getPixelColor(device, 440, 270);
4300     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4301 }
4302
4303 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4304 {
4305     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4306     IDirect3DVertexDeclaration9 *decl;
4307     HRESULT hr;
4308     DWORD color;
4309     DWORD shader_code_11[] =  {
4310         0xfffe0101,                                         /* vs_1_1           */
4311         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4312         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4313         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4314         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4315         0x0000ffff                                          /* end              */
4316     };
4317     DWORD shader_code_11_2[] =  {
4318         0xfffe0101,                                         /* vs_1_1           */
4319         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4320         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4321         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4322         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4323         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4324         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4325         0x0000ffff                                          /* end              */
4326     };
4327     DWORD shader_code_20[] =  {
4328         0xfffe0200,                                         /* vs_2_0           */
4329         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4330         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4331         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4332         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4333         0x0000ffff                                          /* end              */
4334     };
4335     DWORD shader_code_20_2[] =  {
4336         0xfffe0200,                                         /* vs_2_0           */
4337         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4338         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4339         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4340         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4341         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4342         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4343         0x0000ffff                                          /* end              */
4344     };
4345     static const D3DVERTEXELEMENT9 decl_elements[] = {
4346         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4347         D3DDECL_END()
4348     };
4349     float quad1[] = {
4350         -1.0,   -1.0,   0.1,
4351          0.0,   -1.0,   0.1,
4352         -1.0,    0.0,   0.1,
4353          0.0,    0.0,   0.1
4354     };
4355     float quad2[] = {
4356          0.0,   -1.0,   0.1,
4357          1.0,   -1.0,   0.1,
4358          0.0,    0.0,   0.1,
4359          1.0,    0.0,   0.1
4360     };
4361     float quad3[] = {
4362          0.0,    0.0,   0.1,
4363          1.0,    0.0,   0.1,
4364          0.0,    1.0,   0.1,
4365          1.0,    1.0,   0.1
4366     };
4367     float quad4[] = {
4368         -1.0,    0.0,   0.1,
4369          0.0,    0.0,   0.1,
4370         -1.0,    1.0,   0.1,
4371          0.0,    1.0,   0.1
4372     };
4373     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4374     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4375
4376     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4377     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4378
4379     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4380     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4381     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4382     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4383     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4384     if(FAILED(hr)) shader_20 = NULL;
4385     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4386     if(FAILED(hr)) shader_20_2 = NULL;
4387     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4388     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4389
4390     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4391     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4392     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4393     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4394     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4395     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4396
4397     hr = IDirect3DDevice9_BeginScene(device);
4398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4399     if(SUCCEEDED(hr))
4400     {
4401         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4402         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4404         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4405
4406         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4407         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4409         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4410
4411         if(shader_20) {
4412             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4413             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4414             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4415             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4416         }
4417
4418         if(shader_20_2) {
4419             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4420             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4421             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4422             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4423         }
4424
4425         hr = IDirect3DDevice9_EndScene(device);
4426         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4427     }
4428     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4429     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4430
4431     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4432     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4433     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4434     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4435
4436     color = getPixelColor(device, 160, 360);
4437     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4438        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4439     color = getPixelColor(device, 480, 360);
4440     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4441        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4442     if(shader_20) {
4443         color = getPixelColor(device, 160, 120);
4444         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4445            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4446     }
4447     if(shader_20_2) {
4448         color = getPixelColor(device, 480, 120);
4449         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4450            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4451     }
4452
4453     IDirect3DVertexDeclaration9_Release(decl);
4454     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4455     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4456     IDirect3DVertexShader9_Release(shader_11_2);
4457     IDirect3DVertexShader9_Release(shader_11);
4458 }
4459
4460 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4461 {
4462     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4463     HRESULT hr;
4464     DWORD color;
4465     DWORD shader_code_11[] =  {
4466         0xffff0101,                                         /* ps_1_1           */
4467         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4468         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4469         0x0000ffff                                          /* end              */
4470     };
4471     DWORD shader_code_12[] =  {
4472         0xffff0102,                                         /* ps_1_2           */
4473         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4474         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4475         0x0000ffff                                          /* end              */
4476     };
4477     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4478      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4479      * During development of this test, 1.3 shaders were verified too
4480      */
4481     DWORD shader_code_14[] =  {
4482         0xffff0104,                                         /* ps_1_4           */
4483         /* Try to make one constant local. It gets clamped too, although the binary contains
4484          * the bigger numbers
4485          */
4486         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4487         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4488         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4489         0x0000ffff                                          /* end              */
4490     };
4491     DWORD shader_code_20[] =  {
4492         0xffff0200,                                         /* ps_2_0           */
4493         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4494         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4495         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4496         0x0000ffff                                          /* end              */
4497     };
4498     float quad1[] = {
4499         -1.0,   -1.0,   0.1,
4500          0.0,   -1.0,   0.1,
4501         -1.0,    0.0,   0.1,
4502          0.0,    0.0,   0.1
4503     };
4504     float quad2[] = {
4505          0.0,   -1.0,   0.1,
4506          1.0,   -1.0,   0.1,
4507          0.0,    0.0,   0.1,
4508          1.0,    0.0,   0.1
4509     };
4510     float quad3[] = {
4511          0.0,    0.0,   0.1,
4512          1.0,    0.0,   0.1,
4513          0.0,    1.0,   0.1,
4514          1.0,    1.0,   0.1
4515     };
4516     float quad4[] = {
4517         -1.0,    0.0,   0.1,
4518          0.0,    0.0,   0.1,
4519         -1.0,    1.0,   0.1,
4520          0.0,    1.0,   0.1
4521     };
4522     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4523     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4524
4525     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4526     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4527
4528     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4529     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4530     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4531     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4532     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4533     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4534     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4535     if(FAILED(hr)) shader_20 = NULL;
4536
4537     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4538     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4539     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4541     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4542     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4543
4544     hr = IDirect3DDevice9_BeginScene(device);
4545     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4546     if(SUCCEEDED(hr))
4547     {
4548         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4549         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4550         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4551         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4552
4553         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4554         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4555         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4556         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4557
4558         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4559         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4560         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4561         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4562
4563         if(shader_20) {
4564             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4565             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4566             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4567             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4568         }
4569
4570         hr = IDirect3DDevice9_EndScene(device);
4571         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4572     }
4573     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4574     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4575
4576     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4577     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4578
4579     color = getPixelColor(device, 160, 360);
4580     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4581        "quad 1 has color %08x, expected 0x00808000\n", color);
4582     color = getPixelColor(device, 480, 360);
4583     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4584        "quad 2 has color %08x, expected 0x00808000\n", color);
4585     color = getPixelColor(device, 480, 120);
4586     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4587        "quad 3 has color %08x, expected 0x00808000\n", color);
4588     if(shader_20) {
4589         color = getPixelColor(device, 160, 120);
4590         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4591            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4592     }
4593
4594     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4595     IDirect3DPixelShader9_Release(shader_14);
4596     IDirect3DPixelShader9_Release(shader_12);
4597     IDirect3DPixelShader9_Release(shader_11);
4598 }
4599
4600 static void dp2add_ps_test(IDirect3DDevice9 *device)
4601 {
4602     IDirect3DPixelShader9 *shader_dp2add = NULL;
4603     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4604     HRESULT hr;
4605     DWORD color;
4606
4607     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4608      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4609      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4610      * r0 first.
4611      * The result here for the r,g,b components should be roughly 0.5:
4612      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4613     static const DWORD shader_code_dp2add[] =  {
4614         0xffff0200,                                                             /* ps_2_0                       */
4615         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4616
4617         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4618         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4619
4620         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4621         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4622         0x0000ffff                                                              /* end                          */
4623     };
4624
4625     /* Test the _sat modifier, too.  Result here should be:
4626      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4627      *      _SAT: ==> 1.0
4628      *   ADD: (1.0 + -0.5) = 0.5
4629      */
4630     static const DWORD shader_code_dp2add_sat[] =  {
4631         0xffff0200,                                                             /* ps_2_0                           */
4632         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4633
4634         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4635         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4636         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4637
4638         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4639         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4640         0x0000ffff                                                              /* end                              */
4641     };
4642
4643     const float quad[] = {
4644         -1.0,   -1.0,   0.1,
4645          1.0,   -1.0,   0.1,
4646         -1.0,    1.0,   0.1,
4647          1.0,    1.0,   0.1
4648     };
4649
4650
4651     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4652     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4653
4654     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4655     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4656
4657     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4658     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4659
4660     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4661     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4662
4663     if (shader_dp2add) {
4664
4665         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4666         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4667
4668         hr = IDirect3DDevice9_BeginScene(device);
4669         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4670         if(SUCCEEDED(hr))
4671         {
4672             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4673             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4674
4675             hr = IDirect3DDevice9_EndScene(device);
4676             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4677         }
4678         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4679         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4680
4681         color = getPixelColor(device, 360, 240);
4682         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4683                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4684
4685         IDirect3DPixelShader9_Release(shader_dp2add);
4686     } else {
4687         skip("dp2add shader creation failed\n");
4688     }
4689
4690     if (shader_dp2add_sat) {
4691
4692         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4693         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4694
4695         hr = IDirect3DDevice9_BeginScene(device);
4696         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4697         if(SUCCEEDED(hr))
4698         {
4699             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4700             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4701
4702             hr = IDirect3DDevice9_EndScene(device);
4703             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4704         }
4705         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4706         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4707
4708         color = getPixelColor(device, 360, 240);
4709         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4710                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4711
4712         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4713     } else {
4714         skip("dp2add shader creation failed\n");
4715     }
4716
4717     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4718     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4719 }
4720
4721 static void cnd_test(IDirect3DDevice9 *device)
4722 {
4723     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4724     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4725     HRESULT hr;
4726     DWORD color;
4727     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4728      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4729      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4730      */
4731     DWORD shader_code_11[] =  {
4732         0xffff0101,                                                                 /* ps_1_1               */
4733         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4734         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4735         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4736         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4737         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4738         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4739         0x0000ffff                                                                  /* end                  */
4740     };
4741     DWORD shader_code_12[] =  {
4742         0xffff0102,                                                                 /* ps_1_2               */
4743         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4744         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4745         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4746         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4747         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4748         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4749         0x0000ffff                                                                  /* end                  */
4750     };
4751     DWORD shader_code_13[] =  {
4752         0xffff0103,                                                                 /* ps_1_3               */
4753         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4754         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4755         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4756         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4757         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4758         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4759         0x0000ffff                                                                  /* end                  */
4760     };
4761     DWORD shader_code_14[] =  {
4762         0xffff0104,                                                                 /* ps_1_3               */
4763         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4764         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4765         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4766         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4767         0x0000ffff                                                                  /* end                  */
4768     };
4769
4770     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4771      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4772      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4773      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4774      * native CreatePixelShader returns an error.
4775      *
4776      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4777      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4778      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4779      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4780      */
4781     DWORD shader_code_11_coissue[] =  {
4782         0xffff0101,                                                             /* ps_1_1                   */
4783         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4784         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4785         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4786         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4787         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4788         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4789         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4790         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4791         /* 0x40000000 = D3DSI_COISSUE */
4792         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4793         0x0000ffff                                                              /* end                      */
4794     };
4795     DWORD shader_code_12_coissue[] =  {
4796         0xffff0102,                                                             /* ps_1_2                   */
4797         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4798         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4799         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4800         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4801         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4802         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4803         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4804         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4805         /* 0x40000000 = D3DSI_COISSUE */
4806         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4807         0x0000ffff                                                              /* end                      */
4808     };
4809     DWORD shader_code_13_coissue[] =  {
4810         0xffff0103,                                                             /* ps_1_3                   */
4811         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4812         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4813         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4814         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4815         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4816         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4817         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4818         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4819         /* 0x40000000 = D3DSI_COISSUE */
4820         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4821         0x0000ffff                                                              /* end                      */
4822     };
4823     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4824      * compare against 0.5
4825      */
4826     DWORD shader_code_14_coissue[] =  {
4827         0xffff0104,                                                             /* ps_1_4                   */
4828         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4829         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4830         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4831         /* 0x40000000 = D3DSI_COISSUE */
4832         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4833         0x0000ffff                                                              /* end                      */
4834     };
4835     float quad1[] = {
4836         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4837          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4838         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4839          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4840     };
4841     float quad2[] = {
4842          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4843          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4844          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4845          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4846     };
4847     float quad3[] = {
4848          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4849          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4850          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4851          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4852     };
4853     float quad4[] = {
4854         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4855          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4856         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4857          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4858     };
4859     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4860     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4861     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4862     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4863
4864     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4865     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4866
4867     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4868     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4869     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4870     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4871     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4872     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4873     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4874     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4875     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4876     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4877     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4879     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4880     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4881     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4882     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4883
4884     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4885     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4886     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4887     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4888     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4889     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4890
4891     hr = IDirect3DDevice9_BeginScene(device);
4892     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4893     if(SUCCEEDED(hr))
4894     {
4895         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4896         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4897         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4898         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4899
4900         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4901         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4902         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4903         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4904
4905         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4906         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4907         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4908         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4909
4910         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4911         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4912         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4913         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4914
4915         hr = IDirect3DDevice9_EndScene(device);
4916         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4917     }
4918     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4919     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4920
4921     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4922     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4923
4924     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4925     color = getPixelColor(device, 158, 118);
4926     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4927     color = getPixelColor(device, 162, 118);
4928     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4929     color = getPixelColor(device, 158, 122);
4930     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4931     color = getPixelColor(device, 162, 122);
4932     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4933
4934     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4935     color = getPixelColor(device, 158, 358);
4936     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4937     color = getPixelColor(device, 162, 358);
4938     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4939         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4940     color = getPixelColor(device, 158, 362);
4941     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4942     color = getPixelColor(device, 162, 362);
4943     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4944         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4945
4946     /* 1.2 shader */
4947     color = getPixelColor(device, 478, 358);
4948     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4949     color = getPixelColor(device, 482, 358);
4950     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4951         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4952     color = getPixelColor(device, 478, 362);
4953     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4954     color = getPixelColor(device, 482, 362);
4955     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4956         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4957
4958     /* 1.3 shader */
4959     color = getPixelColor(device, 478, 118);
4960     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4961     color = getPixelColor(device, 482, 118);
4962     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4963         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4964     color = getPixelColor(device, 478, 122);
4965     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4966     color = getPixelColor(device, 482, 122);
4967     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4968         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4969
4970     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4971     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4972     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4973     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4974     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4975     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4976
4977     hr = IDirect3DDevice9_BeginScene(device);
4978     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4979     if(SUCCEEDED(hr))
4980     {
4981         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4982         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4984         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4985
4986         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4987         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4988         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4989         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4990
4991         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4992         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4993         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4994         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4995
4996         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4997         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4998         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4999         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5000
5001         hr = IDirect3DDevice9_EndScene(device);
5002         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5003     }
5004     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5005     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5006
5007     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5008     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5009
5010     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5011      * that we swapped the values in c1 and c2 to make the other tests return some color
5012      */
5013     color = getPixelColor(device, 158, 118);
5014     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5015     color = getPixelColor(device, 162, 118);
5016     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5017     color = getPixelColor(device, 158, 122);
5018     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5019     color = getPixelColor(device, 162, 122);
5020     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5021
5022     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5023     color = getPixelColor(device, 158, 358);
5024     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5025         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5026     color = getPixelColor(device, 162, 358);
5027     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5028         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5029     color = getPixelColor(device, 158, 362);
5030     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5031         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5032     color = getPixelColor(device, 162, 362);
5033     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5034         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5035
5036     /* 1.2 shader */
5037     color = getPixelColor(device, 478, 358);
5038     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5039         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5040     color = getPixelColor(device, 482, 358);
5041     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5042         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5043     color = getPixelColor(device, 478, 362);
5044     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5045         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5046     color = getPixelColor(device, 482, 362);
5047     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5048         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5049
5050     /* 1.3 shader */
5051     color = getPixelColor(device, 478, 118);
5052     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5053         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5054     color = getPixelColor(device, 482, 118);
5055     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5056         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5057     color = getPixelColor(device, 478, 122);
5058     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5059         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5060     color = getPixelColor(device, 482, 122);
5061     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5062         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5063
5064     IDirect3DPixelShader9_Release(shader_14_coissue);
5065     IDirect3DPixelShader9_Release(shader_13_coissue);
5066     IDirect3DPixelShader9_Release(shader_12_coissue);
5067     IDirect3DPixelShader9_Release(shader_11_coissue);
5068     IDirect3DPixelShader9_Release(shader_14);
5069     IDirect3DPixelShader9_Release(shader_13);
5070     IDirect3DPixelShader9_Release(shader_12);
5071     IDirect3DPixelShader9_Release(shader_11);
5072 }
5073
5074 static void nested_loop_test(IDirect3DDevice9 *device) {
5075     const DWORD shader_code[] = {
5076         0xffff0300,                                                             /* ps_3_0               */
5077         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5078         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5079         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5080         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5081         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5082         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5083         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5084         0x0000001d,                                                             /* endloop              */
5085         0x0000001d,                                                             /* endloop              */
5086         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5087         0x0000ffff                                                              /* end                  */
5088     };
5089     IDirect3DPixelShader9 *shader;
5090     HRESULT hr;
5091     DWORD color;
5092     const float quad[] = {
5093         -1.0,   -1.0,   0.1,
5094          1.0,   -1.0,   0.1,
5095         -1.0,    1.0,   0.1,
5096          1.0,    1.0,   0.1
5097     };
5098
5099     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5100     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5101     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5102     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5103     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5104     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5105     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5106     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5107
5108     hr = IDirect3DDevice9_BeginScene(device);
5109     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5110     if(SUCCEEDED(hr))
5111     {
5112         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5113         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5114         hr = IDirect3DDevice9_EndScene(device);
5115         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5116     }
5117     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5118     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5119
5120     color = getPixelColor(device, 360, 240);
5121     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5122        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5123
5124     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5125     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5126     IDirect3DPixelShader9_Release(shader);
5127 }
5128
5129 struct varying_test_struct
5130 {
5131     const DWORD             *shader_code;
5132     IDirect3DPixelShader9   *shader;
5133     DWORD                   color, color_rhw;
5134     const char              *name;
5135     BOOL                    todo, todo_rhw;
5136 };
5137
5138 struct hugeVertex
5139 {
5140     float pos_x,        pos_y,      pos_z,      rhw;
5141     float weight_1,     weight_2,   weight_3,   weight_4;
5142     float index_1,      index_2,    index_3,    index_4;
5143     float normal_1,     normal_2,   normal_3,   normal_4;
5144     float fog_1,        fog_2,      fog_3,      fog_4;
5145     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5146     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5147     float binormal_1,   binormal_2, binormal_3, binormal_4;
5148     float depth_1,      depth_2,    depth_3,    depth_4;
5149     DWORD diffuse, specular;
5150 };
5151
5152 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5153     /* dcl_position: fails to compile */
5154     const DWORD blendweight_code[] = {
5155         0xffff0300,                             /* ps_3_0                   */
5156         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5157         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5158         0x0000ffff                              /* end                      */
5159     };
5160     const DWORD blendindices_code[] = {
5161         0xffff0300,                             /* ps_3_0                   */
5162         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5163         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5164         0x0000ffff                              /* end                      */
5165     };
5166     const DWORD normal_code[] = {
5167         0xffff0300,                             /* ps_3_0                   */
5168         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5169         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5170         0x0000ffff                              /* end                      */
5171     };
5172     /* psize: fails? */
5173     const DWORD texcoord0_code[] = {
5174         0xffff0300,                             /* ps_3_0                   */
5175         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5176         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5177         0x0000ffff                              /* end                      */
5178     };
5179     const DWORD tangent_code[] = {
5180         0xffff0300,                             /* ps_3_0                   */
5181         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5182         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5183         0x0000ffff                              /* end                      */
5184     };
5185     const DWORD binormal_code[] = {
5186         0xffff0300,                             /* ps_3_0                   */
5187         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5188         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5189         0x0000ffff                              /* end                      */
5190     };
5191     /* tessfactor: fails */
5192     /* positiont: fails */
5193     const DWORD color_code[] = {
5194         0xffff0300,                             /* ps_3_0                   */
5195         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5196         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5197         0x0000ffff                              /* end                      */
5198     };
5199     const DWORD fog_code[] = {
5200         0xffff0300,                             /* ps_3_0                   */
5201         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5202         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5203         0x0000ffff                              /* end                      */
5204     };
5205     const DWORD depth_code[] = {
5206         0xffff0300,                             /* ps_3_0                   */
5207         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5208         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5209         0x0000ffff                              /* end                      */
5210     };
5211     const DWORD specular_code[] = {
5212         0xffff0300,                             /* ps_3_0                   */
5213         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5214         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5215         0x0000ffff                              /* end                      */
5216     };
5217     /* sample: fails */
5218
5219     struct varying_test_struct tests[] = {
5220        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5221        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5222        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5223        /* Why does dx not forward the texcoord? */
5224        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5225        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5226        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5227        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5228        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5229        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5230        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5231     };
5232     /* Declare a monster vertex type :-) */
5233     static const D3DVERTEXELEMENT9 decl_elements[] = {
5234         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5235         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5236         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5237         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5238         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5239         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5240         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5241         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5242         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5243         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5244         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5245         D3DDECL_END()
5246     };
5247     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5248         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5249         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5250         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5251         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5252         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5253         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5254         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5255         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5256         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5257         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5258         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5259         D3DDECL_END()
5260     };
5261     struct hugeVertex data[4] = {
5262         {
5263             -1.0,   -1.0,   0.1,    1.0,
5264              0.1,    0.1,   0.1,    0.1,
5265              0.2,    0.2,   0.2,    0.2,
5266              0.3,    0.3,   0.3,    0.3,
5267              0.4,    0.4,   0.4,    0.4,
5268              0.50,   0.55,  0.55,   0.55,
5269              0.6,    0.6,   0.6,    0.7,
5270              0.7,    0.7,   0.7,    0.6,
5271              0.8,    0.8,   0.8,    0.8,
5272              0xe6e6e6e6, /* 0.9 * 256 */
5273              0x224488ff  /* Nothing special */
5274         },
5275         {
5276              1.0,   -1.0,   0.1,    1.0,
5277              0.1,    0.1,   0.1,    0.1,
5278              0.2,    0.2,   0.2,    0.2,
5279              0.3,    0.3,   0.3,    0.3,
5280              0.4,    0.4,   0.4,    0.4,
5281              0.50,   0.55,  0.55,   0.55,
5282              0.6,    0.6,   0.6,    0.7,
5283              0.7,    0.7,   0.7,    0.6,
5284              0.8,    0.8,   0.8,    0.8,
5285              0xe6e6e6e6, /* 0.9 * 256 */
5286              0x224488ff /* Nothing special */
5287         },
5288         {
5289             -1.0,    1.0,   0.1,    1.0,
5290              0.1,    0.1,   0.1,    0.1,
5291              0.2,    0.2,   0.2,    0.2,
5292              0.3,    0.3,   0.3,    0.3,
5293              0.4,    0.4,   0.4,    0.4,
5294              0.50,   0.55,  0.55,   0.55,
5295              0.6,    0.6,   0.6,    0.7,
5296              0.7,    0.7,   0.7,    0.6,
5297              0.8,    0.8,   0.8,    0.8,
5298              0xe6e6e6e6, /* 0.9 * 256 */
5299              0x224488ff /* Nothing special */
5300         },
5301         {
5302              1.0,    1.0,   0.1,    1.0,
5303              0.1,    0.1,   0.1,    0.1,
5304              0.2,    0.2,   0.2,    0.2,
5305              0.3,    0.3,   0.3,    0.3,
5306              0.4,    0.4,   0.4,    0.4,
5307              0.50,   0.55,  0.55,   0.55,
5308              0.6,    0.6,   0.6,    0.7,
5309              0.7,    0.7,   0.7,    0.6,
5310              0.8,    0.8,   0.8,    0.8,
5311              0xe6e6e6e6, /* 0.9 * 256 */
5312              0x224488ff /* Nothing special */
5313         },
5314     };
5315     struct hugeVertex data2[4];
5316     IDirect3DVertexDeclaration9 *decl;
5317     IDirect3DVertexDeclaration9 *decl2;
5318     HRESULT hr;
5319     unsigned int i;
5320     DWORD color, r, g, b, r_e, g_e, b_e;
5321     BOOL drawok;
5322
5323     memcpy(data2, data, sizeof(data2));
5324     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5325     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5326     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5327     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5328
5329     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5330     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5331     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5333     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5334     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5335
5336     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5337     {
5338         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5339         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5340            tests[i].name, hr);
5341     }
5342
5343     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5344     {
5345         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5346         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5347
5348         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5349         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5350
5351         hr = IDirect3DDevice9_BeginScene(device);
5352         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5353         drawok = FALSE;
5354         if(SUCCEEDED(hr))
5355         {
5356             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5357             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5358             drawok = SUCCEEDED(hr);
5359             hr = IDirect3DDevice9_EndScene(device);
5360             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5361         }
5362         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5363         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5364
5365         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5366          * the failure and do not check the color if it failed
5367          */
5368         if(!drawok) {
5369             continue;
5370         }
5371
5372         color = getPixelColor(device, 360, 240);
5373         r = color & 0x00ff0000 >> 16;
5374         g = color & 0x0000ff00 >>  8;
5375         b = color & 0x000000ff;
5376         r_e = tests[i].color & 0x00ff0000 >> 16;
5377         g_e = tests[i].color & 0x0000ff00 >>  8;
5378         b_e = tests[i].color & 0x000000ff;
5379
5380         if(tests[i].todo) {
5381             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5382                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5383                          tests[i].name, color, tests[i].color);
5384         } else {
5385             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5386                "Test %s returned color 0x%08x, expected 0x%08x\n",
5387                tests[i].name, color, tests[i].color);
5388         }
5389     }
5390
5391     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5392     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5393     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5394     {
5395         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5396         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5397
5398         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5399         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5400
5401         hr = IDirect3DDevice9_BeginScene(device);
5402         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5403         if(SUCCEEDED(hr))
5404         {
5405             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5406             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5407             hr = IDirect3DDevice9_EndScene(device);
5408             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5409         }
5410         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5411         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5412
5413         color = getPixelColor(device, 360, 240);
5414         r = color & 0x00ff0000 >> 16;
5415         g = color & 0x0000ff00 >>  8;
5416         b = color & 0x000000ff;
5417         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5418         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5419         b_e = tests[i].color_rhw & 0x000000ff;
5420
5421         if(tests[i].todo_rhw) {
5422             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5423              * pipeline
5424              */
5425             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5426                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5427                          tests[i].name, color, tests[i].color_rhw);
5428         } else {
5429             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5430                "Test %s returned color 0x%08x, expected 0x%08x\n",
5431                tests[i].name, color, tests[i].color_rhw);
5432         }
5433     }
5434
5435     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5436     {
5437         IDirect3DPixelShader9_Release(tests[i].shader);
5438     }
5439
5440     IDirect3DVertexDeclaration9_Release(decl2);
5441     IDirect3DVertexDeclaration9_Release(decl);
5442 }
5443
5444 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5445     static const DWORD ps_code[] = {
5446     0xffff0300,                                                             /* ps_3_0                       */
5447     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5448     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5449     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5450     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5451     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5452     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5453     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5454     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5455     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5456
5457     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5458     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5459     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5460     0x0000001d,                                                             /* endloop                      */
5461     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5462     0x0000ffff                                                              /* end                          */
5463     };
5464     static const DWORD vs_1_code[] = {
5465     0xfffe0101,                                                             /* vs_1_1                       */
5466     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5467     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5468     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5469     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5470     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5471     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5472     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5473     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5474     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5475     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5476     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5477     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5478     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5479     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5480     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5481     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5482     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5483     0x0000ffff
5484     };
5485     DWORD vs_2_code[] = {
5486     0xfffe0200,                                                             /* vs_2_0                       */
5487     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5488     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5489     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5490     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5491     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5492     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5493     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5494     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5495     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5496     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5497     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5498     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5499     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5500     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5501     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5502     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5503     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5504     0x0000ffff                                                              /* end                          */
5505     };
5506     /* TODO: Define normal, tangent, blendweight and depth here */
5507     static const DWORD vs_3_code[] = {
5508     0xfffe0300,                                                             /* vs_3_0                       */
5509     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5510     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5511     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5512     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5513     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5514     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5515     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5516     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5517     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5518     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5519     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5520     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5521     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5522     0x0000ffff                                                              /* end                          */
5523     };
5524     float quad1[] =  {
5525         -1.0,   -1.0,   0.1,
5526          0.0,   -1.0,   0.1,
5527         -1.0,    0.0,   0.1,
5528          0.0,    0.0,   0.1
5529     };
5530     float quad2[] =  {
5531          0.0,   -1.0,   0.1,
5532          1.0,   -1.0,   0.1,
5533          0.0,    0.0,   0.1,
5534          1.0,    0.0,   0.1
5535     };
5536     float quad3[] =  {
5537         -1.0,    0.0,   0.1,
5538          0.0,    0.0,   0.1,
5539         -1.0,    1.0,   0.1,
5540          0.0,    1.0,   0.1
5541     };
5542
5543     HRESULT hr;
5544     DWORD color;
5545     IDirect3DPixelShader9 *pixelshader = NULL;
5546     IDirect3DVertexShader9 *vs_1_shader = NULL;
5547     IDirect3DVertexShader9 *vs_2_shader = NULL;
5548     IDirect3DVertexShader9 *vs_3_shader = NULL;
5549
5550     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5551
5552     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5553     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5554     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5555     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5556     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5557     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5558     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5559     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5560     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5561     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5562     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5563
5564     hr = IDirect3DDevice9_BeginScene(device);
5565     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5566     if(SUCCEEDED(hr))
5567     {
5568         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5569         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5570         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5571         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5572
5573         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5574         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5575         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5576         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5577
5578         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5579         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5580         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5581         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5582
5583         hr = IDirect3DDevice9_EndScene(device);
5584         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5585     }
5586     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5587     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5588
5589     color = getPixelColor(device, 160, 120);
5590     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5591        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5592     /* Accept two ways of oFog handling:
5593      *
5594      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5595      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5596      *
5597      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5598      *    This happens with software vertex processing and on Intel cards
5599      *
5600      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5601      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5602      */
5603     color = getPixelColor(device, 160, 360);
5604     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5605        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5606        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5607     color = getPixelColor(device, 480, 360);
5608     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5609        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5610        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5611
5612     /* cleanup */
5613     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5614     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5615     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5616     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5617     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5618     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5619     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5620     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5621 }
5622
5623 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5624     static const DWORD vs_code[] = {
5625     0xfffe0300,                                                             /* vs_3_0                       */
5626     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5627     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5628     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5629     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5630     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5631     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5632     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5633     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5634     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5635     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5636     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5637     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5638     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5639
5640     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5641     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5642     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5643     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5644     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5645     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5646     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5647     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5648     0x0000ffff                                                              /* end                          */
5649     };
5650     static const DWORD ps_1_code[] = {
5651     0xffff0104,                                                             /* ps_1_4                       */
5652     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5653     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5654     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5655     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5656     0x0000ffff                                                              /* end                          */
5657     };
5658     static const DWORD ps_2_code[] = {
5659     0xffff0200,                                                             /* ps_2_0                       */
5660     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5661     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5662     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5663
5664     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5665     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5666     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5667     0x0000ffff                                                              /* end                          */
5668     };
5669     static const DWORD ps_3_code[] = {
5670     0xffff0300,                                                             /* ps_3_0                       */
5671     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5672     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5673     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5674
5675     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5676     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5677     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5678     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5679     0x0000ffff                                                              /* end                          */
5680     };
5681
5682     float quad1[] =  {
5683         -1.0,   -1.0,   0.1,
5684          0.0,   -1.0,   0.1,
5685         -1.0,    0.0,   0.1,
5686          0.0,    0.0,   0.1
5687     };
5688     float quad2[] =  {
5689          0.0,   -1.0,   0.1,
5690          1.0,   -1.0,   0.1,
5691          0.0,    0.0,   0.1,
5692          1.0,    0.0,   0.1
5693     };
5694     float quad3[] =  {
5695         -1.0,    0.0,   0.1,
5696          0.0,    0.0,   0.1,
5697         -1.0,    1.0,   0.1,
5698          0.0,    1.0,   0.1
5699     };
5700     float quad4[] =  {
5701          0.0,    0.0,   0.1,
5702          1.0,    0.0,   0.1,
5703          0.0,    1.0,   0.1,
5704          1.0,    1.0,   0.1
5705     };
5706
5707     HRESULT hr;
5708     DWORD color;
5709     IDirect3DVertexShader9 *vertexshader = NULL;
5710     IDirect3DPixelShader9 *ps_1_shader = NULL;
5711     IDirect3DPixelShader9 *ps_2_shader = NULL;
5712     IDirect3DPixelShader9 *ps_3_shader = NULL;
5713     IDirect3DTexture9 *texture = NULL;
5714     D3DLOCKED_RECT lr;
5715     unsigned int x, y;
5716
5717     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5718
5719     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5720     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5721     if(FAILED(hr)) {
5722         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5723         return;
5724     }
5725     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5726     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5727     for(y = 0; y < 512; y++) {
5728         for(x = 0; x < 512; x++) {
5729             double r_f = (double) x / (double) 512;
5730             double g_f = (double) y / (double) 512;
5731             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5732             unsigned short r = (unsigned short) (r_f * 65535.0);
5733             unsigned short g = (unsigned short) (g_f * 65535.0);
5734             dst[0] = r;
5735             dst[1] = g;
5736             dst[2] = 0;
5737             dst[3] = 65535;
5738         }
5739     }
5740     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5741     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5742
5743     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5744     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5745     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5746     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5747     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5748     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5749     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5750     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5751     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5752     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5753     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5754
5755     hr = IDirect3DDevice9_BeginScene(device);
5756     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5757     if(SUCCEEDED(hr))
5758     {
5759         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5760         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5761         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5762         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5763
5764         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5765         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5767         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5768
5769         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5770         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5772         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5773
5774         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5775         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5776         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5777         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5778         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5779         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5780         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5781         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5783         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5784
5785         hr = IDirect3DDevice9_EndScene(device);
5786         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5787     }
5788     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5789     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5790
5791     color = getPixelColor(device, 160, 120);
5792     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5793        (color & 0x0000ff00) == 0x0000ff00 &&
5794        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5795        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5796     color = getPixelColor(device, 160, 360);
5797     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5798        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5799        (color & 0x000000ff) == 0x00000000,
5800        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5801     color = getPixelColor(device, 480, 360);
5802     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5803        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5804        (color & 0x000000ff) == 0x00000000,
5805        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5806     color = getPixelColor(device, 480, 160);
5807     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5808        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5809        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5810        (color & 0x000000ff) == 0x00000000),
5811        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5812
5813     /* cleanup */
5814     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5815     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5816     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5817     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5818     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5819     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5820     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5821     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5822     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5823     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5824     if(texture) IDirect3DTexture9_Release(texture);
5825 }
5826
5827 static void test_compare_instructions(IDirect3DDevice9 *device)
5828 {
5829     DWORD shader_sge_vec_code[] = {
5830         0xfffe0101,                                         /* vs_1_1                   */
5831         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5832         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5833         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5834         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5835         0x0000ffff                                          /* end                      */
5836     };
5837     DWORD shader_slt_vec_code[] = {
5838         0xfffe0101,                                         /* vs_1_1                   */
5839         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5840         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5841         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5842         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5843         0x0000ffff                                          /* end                      */
5844     };
5845     DWORD shader_sge_scalar_code[] = {
5846         0xfffe0101,                                         /* vs_1_1                   */
5847         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5848         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5849         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5850         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5851         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5852         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5853         0x0000ffff                                          /* end                      */
5854     };
5855     DWORD shader_slt_scalar_code[] = {
5856         0xfffe0101,                                         /* vs_1_1                   */
5857         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5858         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5859         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5860         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5861         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5862         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5863         0x0000ffff                                          /* end                      */
5864     };
5865     IDirect3DVertexShader9 *shader_sge_vec;
5866     IDirect3DVertexShader9 *shader_slt_vec;
5867     IDirect3DVertexShader9 *shader_sge_scalar;
5868     IDirect3DVertexShader9 *shader_slt_scalar;
5869     HRESULT hr, color;
5870     float quad1[] =  {
5871         -1.0,   -1.0,   0.1,
5872          0.0,   -1.0,   0.1,
5873         -1.0,    0.0,   0.1,
5874          0.0,    0.0,   0.1
5875     };
5876     float quad2[] =  {
5877          0.0,   -1.0,   0.1,
5878          1.0,   -1.0,   0.1,
5879          0.0,    0.0,   0.1,
5880          1.0,    0.0,   0.1
5881     };
5882     float quad3[] =  {
5883         -1.0,    0.0,   0.1,
5884          0.0,    0.0,   0.1,
5885         -1.0,    1.0,   0.1,
5886          0.0,    1.0,   0.1
5887     };
5888     float quad4[] =  {
5889          0.0,    0.0,   0.1,
5890          1.0,    0.0,   0.1,
5891          0.0,    1.0,   0.1,
5892          1.0,    1.0,   0.1
5893     };
5894     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5895     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5896
5897     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5898
5899     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5901     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5903     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5904     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5905     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5906     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5907     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5908     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5909     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5910     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5911     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5912     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5913
5914     hr = IDirect3DDevice9_BeginScene(device);
5915     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5916     if(SUCCEEDED(hr))
5917     {
5918         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5919         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5920         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5921         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5922
5923         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5924         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5925         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5926         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5927
5928         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5929         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5930         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5931         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5932
5933         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5934         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5935
5936         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5937         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5938         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5939         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5940
5941         hr = IDirect3DDevice9_EndScene(device);
5942         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5943     }
5944
5945     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5946     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5947     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5948     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5949
5950     color = getPixelColor(device, 160, 360);
5951     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5952     color = getPixelColor(device, 480, 360);
5953     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5954     color = getPixelColor(device, 160, 120);
5955     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5956     color = getPixelColor(device, 480, 160);
5957     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5958
5959     IDirect3DVertexShader9_Release(shader_sge_vec);
5960     IDirect3DVertexShader9_Release(shader_slt_vec);
5961     IDirect3DVertexShader9_Release(shader_sge_scalar);
5962     IDirect3DVertexShader9_Release(shader_slt_scalar);
5963 }
5964
5965 static void test_vshader_input(IDirect3DDevice9 *device)
5966 {
5967     DWORD swapped_shader_code_3[] = {
5968         0xfffe0300,                                         /* vs_3_0               */
5969         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5970         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5971         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5972         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5973         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5974         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5975         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5976         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5977         0x0000ffff                                          /* end                  */
5978     };
5979     DWORD swapped_shader_code_1[] = {
5980         0xfffe0101,                                         /* vs_1_1               */
5981         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5982         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5983         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5984         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5985         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5986         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5987         0x0000ffff                                          /* end                  */
5988     };
5989     DWORD swapped_shader_code_2[] = {
5990         0xfffe0200,                                         /* vs_2_0               */
5991         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5992         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5993         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5994         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5995         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5996         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5997         0x0000ffff                                          /* end                  */
5998     };
5999     DWORD texcoord_color_shader_code_3[] = {
6000         0xfffe0300,                                         /* vs_3_0               */
6001         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6002         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6003         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6004         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6005         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6006         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6007         0x0000ffff                                          /* end                  */
6008     };
6009     DWORD texcoord_color_shader_code_2[] = {
6010         0xfffe0200,                                         /* vs_2_0               */
6011         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6012         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6013         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6014         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6015         0x0000ffff                                          /* end                  */
6016     };
6017     DWORD texcoord_color_shader_code_1[] = {
6018         0xfffe0101,                                         /* vs_1_1               */
6019         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6020         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6021         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6022         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6023         0x0000ffff                                          /* end                  */
6024     };
6025     DWORD color_color_shader_code_3[] = {
6026         0xfffe0300,                                         /* vs_3_0               */
6027         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6028         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6029         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6030         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6031         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6032         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6033         0x0000ffff                                          /* end                  */
6034     };
6035     DWORD color_color_shader_code_2[] = {
6036         0xfffe0200,                                         /* vs_2_0               */
6037         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6038         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6039         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6040         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6041         0x0000ffff                                          /* end                  */
6042     };
6043     DWORD color_color_shader_code_1[] = {
6044         0xfffe0101,                                         /* vs_1_1               */
6045         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6046         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6047         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6048         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6049         0x0000ffff                                          /* end                  */
6050     };
6051     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6052     HRESULT hr;
6053     DWORD color;
6054     float quad1[] =  {
6055         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6056          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6057         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6058          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6059     };
6060     float quad2[] =  {
6061          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6062          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6063          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6064          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6065     };
6066     float quad3[] =  {
6067         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6068          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6069         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6070          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6071     };
6072     float quad4[] =  {
6073          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6074          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6075          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6076          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6077     };
6078     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6079         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6080         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6081         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6082         D3DDECL_END()
6083     };
6084     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6085         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6086         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6087         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6088         D3DDECL_END()
6089     };
6090     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6091         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6092         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6093         D3DDECL_END()
6094     };
6095     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
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,       2},
6099         D3DDECL_END()
6100     };
6101     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6102         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6103         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6104         D3DDECL_END()
6105     };
6106     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6107         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6108         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6109         D3DDECL_END()
6110     };
6111     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6112         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6113         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6114         D3DDECL_END()
6115     };
6116     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6117         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6118         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6119         D3DDECL_END()
6120     };
6121     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6122     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6123     unsigned int i;
6124     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6125     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6126
6127     struct vertex quad1_color[] =  {
6128        {-1.0,   -1.0,   0.1,    0x00ff8040},
6129        { 0.0,   -1.0,   0.1,    0x00ff8040},
6130        {-1.0,    0.0,   0.1,    0x00ff8040},
6131        { 0.0,    0.0,   0.1,    0x00ff8040}
6132     };
6133     struct vertex quad2_color[] =  {
6134        { 0.0,   -1.0,   0.1,    0x00ff8040},
6135        { 1.0,   -1.0,   0.1,    0x00ff8040},
6136        { 0.0,    0.0,   0.1,    0x00ff8040},
6137        { 1.0,    0.0,   0.1,    0x00ff8040}
6138     };
6139     struct vertex quad3_color[] =  {
6140        {-1.0,    0.0,   0.1,    0x00ff8040},
6141        { 0.0,    0.0,   0.1,    0x00ff8040},
6142        {-1.0,    1.0,   0.1,    0x00ff8040},
6143        { 0.0,    1.0,   0.1,    0x00ff8040}
6144     };
6145     float quad4_color[] =  {
6146          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6147          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6148          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6149          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6150     };
6151
6152     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6153     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6154     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6155     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6156     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6157     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6158     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6159     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6160
6161     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6162     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6163     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6164     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6165     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6166     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6167     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6168     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6169
6170     for(i = 1; i <= 3; i++) {
6171         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6172         if(i == 3) {
6173             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6174             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6175         } else if(i == 2){
6176             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6177             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6178         } else if(i == 1) {
6179             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6180             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6181         }
6182
6183         hr = IDirect3DDevice9_BeginScene(device);
6184         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6185         if(SUCCEEDED(hr))
6186         {
6187             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6188             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6189
6190             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6191             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6192             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6193             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6194
6195             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6196             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6197             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6198             if(i == 3 || i == 2) {
6199                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6200             } else if(i == 1) {
6201                 /* Succeeds or fails, depending on SW or HW vertex processing */
6202                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6203             }
6204
6205             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6206             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6207             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6208             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6209
6210             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6212             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6213             if(i == 3 || i == 2) {
6214                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6215             } else if(i == 1) {
6216                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6217             }
6218
6219             hr = IDirect3DDevice9_EndScene(device);
6220             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6221         }
6222
6223         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6224         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6225
6226         if(i == 3 || i == 2) {
6227             color = getPixelColor(device, 160, 360);
6228             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6229                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6230
6231             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6232             color = getPixelColor(device, 480, 360);
6233             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6234                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6235             color = getPixelColor(device, 160, 120);
6236             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6237             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6238                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6239
6240             color = getPixelColor(device, 480, 160);
6241             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6242         } else if(i == 1) {
6243             color = getPixelColor(device, 160, 360);
6244             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6245                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6246             color = getPixelColor(device, 480, 360);
6247             /* Accept the clear color as well in this case, since SW VP returns an error */
6248             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6249             color = getPixelColor(device, 160, 120);
6250             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6251                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6252             color = getPixelColor(device, 480, 160);
6253             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6254         }
6255
6256         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6257         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6258
6259         /* Now find out if the whole streams are re-read, or just the last active value for the
6260          * vertices is used.
6261          */
6262         hr = IDirect3DDevice9_BeginScene(device);
6263         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6264         if(SUCCEEDED(hr))
6265         {
6266             float quad1_modified[] =  {
6267                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6268                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6269                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6270                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6271             };
6272             float quad2_modified[] =  {
6273                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6274                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6275                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6276                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6277             };
6278
6279             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6280             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6281
6282             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6283             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6284             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6285             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6286
6287             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6288             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6289             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6290             if(i == 3 || i == 2) {
6291                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6292             } else if(i == 1) {
6293                 /* Succeeds or fails, depending on SW or HW vertex processing */
6294                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6295             }
6296
6297             hr = IDirect3DDevice9_EndScene(device);
6298             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6299         }
6300         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6301         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6302
6303         color = getPixelColor(device, 480, 350);
6304         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6305          * as well.
6306          *
6307          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6308          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6309          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6310          * refrast's result.
6311          *
6312          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6313          */
6314         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6315            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6316         color = getPixelColor(device, 160, 120);
6317
6318         IDirect3DDevice9_SetVertexShader(device, NULL);
6319         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6320
6321         IDirect3DVertexShader9_Release(swapped_shader);
6322     }
6323
6324     for(i = 1; i <= 3; i++) {
6325         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6326         if(i == 3) {
6327             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6328             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6329             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6330             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6331         } else if(i == 2){
6332             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6333             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6334             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6335             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6336         } else if(i == 1) {
6337             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6338             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6339             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6340             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6341         }
6342
6343         hr = IDirect3DDevice9_BeginScene(device);
6344         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6345         if(SUCCEEDED(hr))
6346         {
6347             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6348             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6349             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6350             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6351             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6352             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6353
6354             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6355             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6356
6357             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6358             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6359             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6360             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6361             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6362             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6363
6364             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6365             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6366             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6367             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6368             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6369             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6370
6371             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6372             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6373             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6374             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6375
6376             hr = IDirect3DDevice9_EndScene(device);
6377             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6378         }
6379         IDirect3DDevice9_SetVertexShader(device, NULL);
6380         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6381
6382         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6383         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6384
6385         color = getPixelColor(device, 160, 360);
6386         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6387            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6388         color = getPixelColor(device, 480, 360);
6389         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6390            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6391         color = getPixelColor(device, 160, 120);
6392         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6393            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6394         color = getPixelColor(device, 480, 160);
6395         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6396            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6397
6398         IDirect3DVertexShader9_Release(texcoord_color_shader);
6399         IDirect3DVertexShader9_Release(color_color_shader);
6400     }
6401
6402     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6403     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6404     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6405     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6406
6407     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6408     IDirect3DVertexDeclaration9_Release(decl_color_color);
6409     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6410     IDirect3DVertexDeclaration9_Release(decl_color_float);
6411 }
6412
6413 static void srgbtexture_test(IDirect3DDevice9 *device)
6414 {
6415     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6416      * texture stage state to render a quad using that texture.  The resulting
6417      * color components should be 0x36 (~ 0.21), per this formula:
6418      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6419      * This is true where srgb_color > 0.04045.
6420      */
6421     IDirect3D9 *d3d = NULL;
6422     HRESULT hr;
6423     LPDIRECT3DTEXTURE9 texture = NULL;
6424     LPDIRECT3DSURFACE9 surface = NULL;
6425     D3DLOCKED_RECT lr;
6426     DWORD color;
6427     float quad[] = {
6428         -1.0,       1.0,       0.0,     0.0,    0.0,
6429          1.0,       1.0,       0.0,     1.0,    0.0,
6430         -1.0,      -1.0,       0.0,     0.0,    1.0,
6431          1.0,      -1.0,       0.0,     1.0,    1.0,
6432     };
6433
6434
6435     memset(&lr, 0, sizeof(lr));
6436     IDirect3DDevice9_GetDirect3D(device, &d3d);
6437     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6438                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6439                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6440         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6441         goto out;
6442     }
6443
6444     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6445                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6446                                         &texture, NULL);
6447     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6448     if(!texture) {
6449         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6450         goto out;
6451     }
6452     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6453     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6454
6455     fill_surface(surface, 0xff7f7f7f);
6456     IDirect3DSurface9_Release(surface);
6457
6458     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6459     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6460     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6461     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6462
6463     hr = IDirect3DDevice9_BeginScene(device);
6464     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6465     if(SUCCEEDED(hr))
6466     {
6467         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6468         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6469
6470         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6471         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6472
6473
6474         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6475         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6476
6477         hr = IDirect3DDevice9_EndScene(device);
6478         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6479     }
6480
6481     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6482     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6483     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6484     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6485
6486     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6487     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6488
6489     color = getPixelColor(device, 320, 240);
6490     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6491
6492 out:
6493     if(texture) IDirect3DTexture9_Release(texture);
6494     IDirect3D9_Release(d3d);
6495 }
6496
6497 static void shademode_test(IDirect3DDevice9 *device)
6498 {
6499     /* Render a quad and try all of the different fixed function shading models. */
6500     HRESULT hr;
6501     DWORD color0, color1;
6502     DWORD color0_gouraud = 0, color1_gouraud = 0;
6503     DWORD shademode = D3DSHADE_FLAT;
6504     DWORD primtype = D3DPT_TRIANGLESTRIP;
6505     LPVOID data = NULL;
6506     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6507     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6508     UINT i, j;
6509     struct vertex quad_strip[] =
6510     {
6511         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6512         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6513         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6514         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6515     };
6516     struct vertex quad_list[] =
6517     {
6518         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6519         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6520         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6521
6522         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6523         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6524         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6525     };
6526
6527     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6528                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6529     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6530     if (FAILED(hr)) goto bail;
6531
6532     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6533                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6534     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6535     if (FAILED(hr)) goto bail;
6536
6537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6538     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6539
6540     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6541     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6542
6543     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6544     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6545     memcpy(data, quad_strip, sizeof(quad_strip));
6546     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6547     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6548
6549     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6550     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6551     memcpy(data, quad_list, sizeof(quad_list));
6552     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6553     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6554
6555     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6556      * the color fixups we have to do for FLAT shading will be dependent on that. */
6557     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6558     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6559
6560     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6561     for (j=0; j<2; j++) {
6562
6563         /* Inner loop just changes the D3DRS_SHADEMODE */
6564         for (i=0; i<3; i++) {
6565             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6566             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6567
6568             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6569             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6570
6571             hr = IDirect3DDevice9_BeginScene(device);
6572             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6573             if(SUCCEEDED(hr))
6574             {
6575                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6576                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6577
6578                 hr = IDirect3DDevice9_EndScene(device);
6579                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6580             }
6581
6582             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6583             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6584
6585             /* Sample two spots from the output */
6586             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6587             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6588             switch(shademode) {
6589                 case D3DSHADE_FLAT:
6590                     /* Should take the color of the first vertex of each triangle */
6591                     if (0)
6592                     {
6593                         /* This test depends on EXT_provoking_vertex being
6594                          * available. This extension is currently (20090810)
6595                          * not common enough to let the test fail if it isn't
6596                          * present. */
6597                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6598                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6599                     }
6600                     shademode = D3DSHADE_GOURAUD;
6601                     break;
6602                 case D3DSHADE_GOURAUD:
6603                     /* Should be an interpolated blend */
6604
6605                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6606                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6607                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6608                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6609
6610                     color0_gouraud = color0;
6611                     color1_gouraud = color1;
6612
6613                     shademode = D3DSHADE_PHONG;
6614                     break;
6615                 case D3DSHADE_PHONG:
6616                     /* Should be the same as GOURAUD, since no hardware implements this */
6617                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6618                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6619                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6620                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6621
6622                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6623                             color0_gouraud, color0);
6624                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6625                             color1_gouraud, color1);
6626                     break;
6627             }
6628         }
6629         /* Now, do it all over again with a TRIANGLELIST */
6630         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6631         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6632         primtype = D3DPT_TRIANGLELIST;
6633         shademode = D3DSHADE_FLAT;
6634     }
6635
6636 bail:
6637     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6638     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6639     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6640     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6641
6642     if (vb_strip)
6643         IDirect3DVertexBuffer9_Release(vb_strip);
6644     if (vb_list)
6645         IDirect3DVertexBuffer9_Release(vb_list);
6646 }
6647
6648
6649 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6650 {
6651     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6652      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6653      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6654      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6655      * 0.73
6656      *
6657      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6658      * so use shaders for this task
6659      */
6660     IDirect3DPixelShader9 *pshader;
6661     IDirect3DVertexShader9 *vshader;
6662     IDirect3D9 *d3d;
6663     DWORD vshader_code[] = {
6664         0xfffe0101,                                                             /* vs_1_1                       */
6665         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6666         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6667         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6668         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6669         0x0000ffff                                                              /* end                          */
6670     };
6671     DWORD pshader_code[] = {
6672         0xffff0101,                                                             /* ps_1_1                       */
6673         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6674         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6675         0x0000ffff                                                              /* end                          */
6676     };
6677     const float quad[] = {
6678        -1.0,   -1.0,    0.1,
6679         1.0,   -1.0,    0.1,
6680        -1.0,    1.0,    0.1,
6681         1.0,    1.0,    0.1
6682     };
6683     HRESULT hr;
6684     D3DCOLOR color;
6685
6686     IDirect3DDevice9_GetDirect3D(device, &d3d);
6687     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6688      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6689      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6690      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6691      * works
6692      */
6693     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6694                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6695                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6696         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6697         IDirect3D9_Release(d3d);
6698         return;
6699     }
6700     IDirect3D9_Release(d3d);
6701
6702     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6703     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6704
6705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6706     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6707     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6708     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6709     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6710     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6711     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6712     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6713     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6714     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6715
6716     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6717     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6718     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6719     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6720     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6721     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6722     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6723     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6724     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6725     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6726
6727     hr = IDirect3DDevice9_BeginScene(device);
6728     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6729     if(SUCCEEDED(hr)) {
6730         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6731         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6732
6733         hr = IDirect3DDevice9_EndScene(device);
6734         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6735     }
6736
6737     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6738     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6739     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6740     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6741     IDirect3DPixelShader9_Release(pshader);
6742     IDirect3DVertexShader9_Release(vshader);
6743
6744     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6745     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6746     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6747     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6748
6749     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6750     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6751     color = getPixelColor(device, 160, 360);
6752     ok(color_match(color, 0x00808080, 1),
6753             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6754 }
6755
6756 static void alpha_test(IDirect3DDevice9 *device)
6757 {
6758     HRESULT hr;
6759     IDirect3DTexture9 *offscreenTexture;
6760     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6761     DWORD color;
6762
6763     struct vertex quad1[] =
6764     {
6765         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6766         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6767         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6768         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6769     };
6770     struct vertex quad2[] =
6771     {
6772         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6773         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6774         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6775         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6776     };
6777     static const float composite_quad[][5] = {
6778         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6779         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6780         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6781         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6782     };
6783
6784     /* Clear the render target with alpha = 0.5 */
6785     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6786     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6787
6788     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6789     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6790
6791     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6792     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6793     if(!backbuffer) {
6794         goto out;
6795     }
6796
6797     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6798     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6799     if(!offscreen) {
6800         goto out;
6801     }
6802
6803     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6804     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6805
6806     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6807     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6808     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6809     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6810     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6811     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6812     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6813     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6814     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6815     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6816
6817     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6818     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6819     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6820
6821         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6822         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6823         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6824         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6825         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6826         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6827         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6828
6829         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6830         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6831         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6832         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6833         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6834         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6835
6836         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6837          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6838          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6839         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6840         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6841         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6842         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6843
6844         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6845         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6846         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6847         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6848         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6849         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6850
6851         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6852         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6853         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6854         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6855         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6856         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6857
6858         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6859         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6860
6861         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6862          * Disable alpha blending for the final composition
6863          */
6864         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6865         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6866         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6867         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6868
6869         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6870         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6872         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6873         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6874         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6875
6876         hr = IDirect3DDevice9_EndScene(device);
6877         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6878     }
6879
6880     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6881
6882     color = getPixelColor(device, 160, 360);
6883     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6884        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6885
6886     color = getPixelColor(device, 160, 120);
6887     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6888        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6889
6890     color = getPixelColor(device, 480, 360);
6891     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6892        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6893
6894     color = getPixelColor(device, 480, 120);
6895     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6896        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6897
6898     out:
6899     /* restore things */
6900     if(backbuffer) {
6901         IDirect3DSurface9_Release(backbuffer);
6902     }
6903     if(offscreenTexture) {
6904         IDirect3DTexture9_Release(offscreenTexture);
6905     }
6906     if(offscreen) {
6907         IDirect3DSurface9_Release(offscreen);
6908     }
6909 }
6910
6911 struct vertex_shortcolor {
6912     float x, y, z;
6913     unsigned short r, g, b, a;
6914 };
6915 struct vertex_floatcolor {
6916     float x, y, z;
6917     float r, g, b, a;
6918 };
6919
6920 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6921 {
6922     HRESULT hr;
6923     BOOL s_ok, ub_ok, f_ok;
6924     DWORD color, size, i;
6925     void *data;
6926     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6927         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6928         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6929         D3DDECL_END()
6930     };
6931     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6932         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6933         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6934         D3DDECL_END()
6935     };
6936     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6937         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6938         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6939         D3DDECL_END()
6940     };
6941     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6942         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6943         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6944         D3DDECL_END()
6945     };
6946     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6947         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6948         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6949         D3DDECL_END()
6950     };
6951     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6952         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6953         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6954         D3DDECL_END()
6955     };
6956     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6957         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6958         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6959         D3DDECL_END()
6960     };
6961     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6962     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6963     IDirect3DVertexBuffer9 *vb, *vb2;
6964     struct vertex quad1[] =                             /* D3DCOLOR */
6965     {
6966         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6967         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6968         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6969         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6970     };
6971     struct vertex quad2[] =                             /* UBYTE4N */
6972     {
6973         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6974         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6975         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6976         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6977     };
6978     struct vertex_shortcolor quad3[] =                  /* short */
6979     {
6980         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6981         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6982         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6983         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6984     };
6985     struct vertex_floatcolor quad4[] =
6986     {
6987         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6988         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6989         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6990         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6991     };
6992     DWORD colors[] = {
6993         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6994         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6995         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6996         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6997         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6998         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6999         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7000         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7001         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7002         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7003         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7004         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7005         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7006         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7007         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7008         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7009     };
7010     float quads[] = {
7011         -1.0,   -1.0,     0.1,
7012         -1.0,    0.0,     0.1,
7013          0.0,   -1.0,     0.1,
7014          0.0,    0.0,     0.1,
7015
7016          0.0,   -1.0,     0.1,
7017          0.0,    0.0,     0.1,
7018          1.0,   -1.0,     0.1,
7019          1.0,    0.0,     0.1,
7020
7021          0.0,    0.0,     0.1,
7022          0.0,    1.0,     0.1,
7023          1.0,    0.0,     0.1,
7024          1.0,    1.0,     0.1,
7025
7026         -1.0,    0.0,     0.1,
7027         -1.0,    1.0,     0.1,
7028          0.0,    0.0,     0.1,
7029          0.0,    1.0,     0.1
7030     };
7031     struct tvertex quad_transformed[] = {
7032        {  90,    110,     0.1,      2.0,        0x00ffff00},
7033        { 570,    110,     0.1,      2.0,        0x00ffff00},
7034        {  90,    300,     0.1,      2.0,        0x00ffff00},
7035        { 570,    300,     0.1,      2.0,        0x00ffff00}
7036     };
7037     D3DCAPS9 caps;
7038
7039     memset(&caps, 0, sizeof(caps));
7040     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7041     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7042
7043     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7044     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7045
7046     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7047     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7048     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7049     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7050     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7051     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7052     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7053         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7054         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7055         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7056         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7057     } else {
7058         trace("D3DDTCAPS_UBYTE4N not supported\n");
7059         dcl_ubyte_2 = NULL;
7060         dcl_ubyte = NULL;
7061     }
7062     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7063     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7064     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7065     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7066
7067     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7068     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7069                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7070     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7071
7072     hr = IDirect3DDevice9_BeginScene(device);
7073     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7074     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7075     if(SUCCEEDED(hr)) {
7076         if(dcl_color) {
7077             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7078             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7079             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7080             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7081         }
7082
7083         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7084          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7085          * using software vertex processing. Doh!
7086          */
7087         if(dcl_ubyte) {
7088             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7089             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7090             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7091             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7092             ub_ok = SUCCEEDED(hr);
7093         }
7094
7095         if(dcl_short) {
7096             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7097             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7098             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7099             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7100             s_ok = SUCCEEDED(hr);
7101         }
7102
7103         if(dcl_float) {
7104             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7105             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7106             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7107             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7108             f_ok = SUCCEEDED(hr);
7109         }
7110
7111         hr = IDirect3DDevice9_EndScene(device);
7112         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7113     }
7114
7115     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7116     if(dcl_short) {
7117         color = getPixelColor(device, 480, 360);
7118         ok(color == 0x000000ff || !s_ok,
7119            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7120     }
7121     if(dcl_ubyte) {
7122         color = getPixelColor(device, 160, 120);
7123         ok(color == 0x0000ffff || !ub_ok,
7124            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7125     }
7126     if(dcl_color) {
7127         color = getPixelColor(device, 160, 360);
7128         ok(color == 0x00ffff00,
7129            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7130     }
7131     if(dcl_float) {
7132         color = getPixelColor(device, 480, 120);
7133         ok(color == 0x00ff0000 || !f_ok,
7134            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7135     }
7136
7137     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7138      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7139      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7140      * whether the immediate mode code works
7141      */
7142     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7143     hr = IDirect3DDevice9_BeginScene(device);
7144     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7145     if(SUCCEEDED(hr)) {
7146         if(dcl_color) {
7147             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7148             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7149             memcpy(data, quad1, sizeof(quad1));
7150             hr = IDirect3DVertexBuffer9_Unlock(vb);
7151             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7152             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7153             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7154             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7155             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7156             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7157             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7158         }
7159
7160         if(dcl_ubyte) {
7161             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7162             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7163             memcpy(data, quad2, sizeof(quad2));
7164             hr = IDirect3DVertexBuffer9_Unlock(vb);
7165             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7166             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7167             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7168             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7169             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7170             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7171             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7172                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7173             ub_ok = SUCCEEDED(hr);
7174         }
7175
7176         if(dcl_short) {
7177             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7178             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7179             memcpy(data, quad3, sizeof(quad3));
7180             hr = IDirect3DVertexBuffer9_Unlock(vb);
7181             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7182             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7183             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7184             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7185             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7186             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7187             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7188                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7189             s_ok = SUCCEEDED(hr);
7190         }
7191
7192         if(dcl_float) {
7193             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7194             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7195             memcpy(data, quad4, sizeof(quad4));
7196             hr = IDirect3DVertexBuffer9_Unlock(vb);
7197             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7198             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7199             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7200             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7201             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7202             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7203             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7204                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7205             f_ok = SUCCEEDED(hr);
7206         }
7207
7208         hr = IDirect3DDevice9_EndScene(device);
7209         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7210     }
7211
7212     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7213     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7214     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7216
7217     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7218     if(dcl_short) {
7219         color = getPixelColor(device, 480, 360);
7220         ok(color == 0x000000ff || !s_ok,
7221            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7222     }
7223     if(dcl_ubyte) {
7224         color = getPixelColor(device, 160, 120);
7225         ok(color == 0x0000ffff || !ub_ok,
7226            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7227     }
7228     if(dcl_color) {
7229         color = getPixelColor(device, 160, 360);
7230         ok(color == 0x00ffff00,
7231            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7232     }
7233     if(dcl_float) {
7234         color = getPixelColor(device, 480, 120);
7235         ok(color == 0x00ff0000 || !f_ok,
7236            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7237     }
7238
7239     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7240     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7241
7242     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7243     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7244     memcpy(data, quad_transformed, sizeof(quad_transformed));
7245     hr = IDirect3DVertexBuffer9_Unlock(vb);
7246     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7247
7248     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7249     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7250
7251     hr = IDirect3DDevice9_BeginScene(device);
7252     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7253     if(SUCCEEDED(hr)) {
7254         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7255         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7256         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7258
7259         hr = IDirect3DDevice9_EndScene(device);
7260         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7261     }
7262
7263     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7264     color = getPixelColor(device, 88, 108);
7265     ok(color == 0x000000ff,
7266        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7267     color = getPixelColor(device, 92, 108);
7268     ok(color == 0x000000ff,
7269        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7270     color = getPixelColor(device, 88, 112);
7271     ok(color == 0x000000ff,
7272        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7273     color = getPixelColor(device, 92, 112);
7274     ok(color == 0x00ffff00,
7275        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7276
7277     color = getPixelColor(device, 568, 108);
7278     ok(color == 0x000000ff,
7279        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7280     color = getPixelColor(device, 572, 108);
7281     ok(color == 0x000000ff,
7282        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7283     color = getPixelColor(device, 568, 112);
7284     ok(color == 0x00ffff00,
7285        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7286     color = getPixelColor(device, 572, 112);
7287     ok(color == 0x000000ff,
7288        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7289
7290     color = getPixelColor(device, 88, 298);
7291     ok(color == 0x000000ff,
7292        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7293     color = getPixelColor(device, 92, 298);
7294     ok(color == 0x00ffff00,
7295        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7296     color = getPixelColor(device, 88, 302);
7297     ok(color == 0x000000ff,
7298        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7299     color = getPixelColor(device, 92, 302);
7300     ok(color == 0x000000ff,
7301        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7302
7303     color = getPixelColor(device, 568, 298);
7304     ok(color == 0x00ffff00,
7305        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7306     color = getPixelColor(device, 572, 298);
7307     ok(color == 0x000000ff,
7308        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7309     color = getPixelColor(device, 568, 302);
7310     ok(color == 0x000000ff,
7311        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7312     color = getPixelColor(device, 572, 302);
7313     ok(color == 0x000000ff,
7314        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7315
7316     /* This test is pointless without those two declarations: */
7317     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7318         skip("color-ubyte switching test declarations aren't supported\n");
7319         goto out;
7320     }
7321
7322     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7323     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7324     memcpy(data, quads, sizeof(quads));
7325     hr = IDirect3DVertexBuffer9_Unlock(vb);
7326     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7327     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7328                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7329     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7330     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7331     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7332     memcpy(data, colors, sizeof(colors));
7333     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7334     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7335
7336     for(i = 0; i < 2; i++) {
7337         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7338         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7339
7340         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7341         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7342         if(i == 0) {
7343             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7344         } else {
7345             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7346         }
7347         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7348
7349         hr = IDirect3DDevice9_BeginScene(device);
7350         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7351         ub_ok = FALSE;
7352         if(SUCCEEDED(hr)) {
7353             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7354             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7355             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7356             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7357                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7358             ub_ok = SUCCEEDED(hr);
7359
7360             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7361             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7362             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7363             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7364
7365             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7366             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7367             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7368             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7369                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7370             ub_ok = (SUCCEEDED(hr) && ub_ok);
7371
7372             hr = IDirect3DDevice9_EndScene(device);
7373             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7374         }
7375
7376         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7377         if(i == 0) {
7378             color = getPixelColor(device, 480, 360);
7379             ok(color == 0x00ff0000,
7380                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7381             color = getPixelColor(device, 160, 120);
7382             ok(color == 0x00ffffff,
7383                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7384             color = getPixelColor(device, 160, 360);
7385             ok(color == 0x000000ff || !ub_ok,
7386                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7387             color = getPixelColor(device, 480, 120);
7388             ok(color == 0x000000ff || !ub_ok,
7389                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7390         } else {
7391             color = getPixelColor(device, 480, 360);
7392             ok(color == 0x000000ff,
7393                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7394             color = getPixelColor(device, 160, 120);
7395             ok(color == 0x00ffffff,
7396                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7397             color = getPixelColor(device, 160, 360);
7398             ok(color == 0x00ff0000 || !ub_ok,
7399                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7400             color = getPixelColor(device, 480, 120);
7401             ok(color == 0x00ff0000 || !ub_ok,
7402                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7403         }
7404     }
7405
7406     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7407     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7408     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7409     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7410     IDirect3DVertexBuffer9_Release(vb2);
7411
7412     out:
7413     IDirect3DVertexBuffer9_Release(vb);
7414     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7415     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7416     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7417     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7418     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7419     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7420     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7421 }
7422
7423 struct vertex_float16color {
7424     float x, y, z;
7425     DWORD c1, c2;
7426 };
7427
7428 static void test_vshader_float16(IDirect3DDevice9 *device)
7429 {
7430     HRESULT hr;
7431     DWORD color;
7432     void *data;
7433     static const D3DVERTEXELEMENT9 decl_elements[] = {
7434         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7435         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7436         D3DDECL_END()
7437     };
7438     IDirect3DVertexDeclaration9 *vdecl = NULL;
7439     IDirect3DVertexBuffer9 *buffer = NULL;
7440     IDirect3DVertexShader9 *shader;
7441     DWORD shader_code[] = {
7442         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7443         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7444         0x90e40001, 0x0000ffff
7445     };
7446     struct vertex_float16color quad[] = {
7447         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7448         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7449         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7450         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7451
7452         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7453         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7454         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7455         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7456
7457         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7458         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7459         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7460         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7461
7462         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7463         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7464         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7465         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7466     };
7467
7468     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7469     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7470
7471     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7472     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7473     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7474     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7475     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7476     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7477
7478     hr = IDirect3DDevice9_BeginScene(device);
7479     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7480     if(SUCCEEDED(hr)) {
7481         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7482         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7483         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7484         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7485         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7486         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7487         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7488         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7490         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7491
7492         hr = IDirect3DDevice9_EndScene(device);
7493         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7494     }
7495     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7496     color = getPixelColor(device, 480, 360);
7497     ok(color == 0x00ff0000,
7498        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7499     color = getPixelColor(device, 160, 120);
7500     ok(color == 0x00000000,
7501        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7502     color = getPixelColor(device, 160, 360);
7503     ok(color == 0x0000ff00,
7504        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7505     color = getPixelColor(device, 480, 120);
7506     ok(color == 0x000000ff,
7507        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7508
7509     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7510     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7511
7512     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7513                                              D3DPOOL_MANAGED, &buffer, NULL);
7514     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7515     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7516     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7517     memcpy(data, quad, sizeof(quad));
7518     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7519     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7520     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7521     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7522
7523     hr = IDirect3DDevice9_BeginScene(device);
7524     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7525     if(SUCCEEDED(hr)) {
7526             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7527             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7528             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7529             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7530             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7531             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7532             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7533             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7534
7535             hr = IDirect3DDevice9_EndScene(device);
7536             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7537     }
7538
7539     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7540     color = getPixelColor(device, 480, 360);
7541     ok(color == 0x00ff0000,
7542        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7543     color = getPixelColor(device, 160, 120);
7544     ok(color == 0x00000000,
7545        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7546     color = getPixelColor(device, 160, 360);
7547     ok(color == 0x0000ff00,
7548        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7549     color = getPixelColor(device, 480, 120);
7550     ok(color == 0x000000ff,
7551        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7552
7553     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7554     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7555     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7556     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7557     IDirect3DDevice9_SetVertexShader(device, NULL);
7558     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7559
7560     IDirect3DVertexDeclaration9_Release(vdecl);
7561     IDirect3DVertexShader9_Release(shader);
7562     IDirect3DVertexBuffer9_Release(buffer);
7563 }
7564
7565 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7566 {
7567     D3DCAPS9 caps;
7568     IDirect3DTexture9 *texture;
7569     HRESULT hr;
7570     D3DLOCKED_RECT rect;
7571     unsigned int x, y;
7572     DWORD *dst, color;
7573     const float quad[] = {
7574         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7575          1.0,   -1.0,   0.1,    1.2,   -0.2,
7576         -1.0,    1.0,   0.1,   -0.2,    1.2,
7577          1.0,    1.0,   0.1,    1.2,    1.2
7578     };
7579     memset(&caps, 0, sizeof(caps));
7580
7581     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7582     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7583     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7584         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7585         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7586            "Card has conditional NP2 support without power of two restriction set\n");
7587         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7588         return;
7589     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7590         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7591         return;
7592     }
7593
7594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7595     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7596
7597     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7598     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7599
7600     memset(&rect, 0, sizeof(rect));
7601     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7602     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7603     for(y = 0; y < 10; y++) {
7604         for(x = 0; x < 10; x++) {
7605             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7606             if(x == 0 || x == 9 || y == 0 || y == 9) {
7607                 *dst = 0x00ff0000;
7608             } else {
7609                 *dst = 0x000000ff;
7610             }
7611         }
7612     }
7613     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7614     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7615
7616     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7617     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7618     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7619     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7620     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7621     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7623     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7624
7625     hr = IDirect3DDevice9_BeginScene(device);
7626     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7627     if(SUCCEEDED(hr)) {
7628         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7629         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7630
7631         hr = IDirect3DDevice9_EndScene(device);
7632         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7633     }
7634
7635     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7636
7637     color = getPixelColor(device,    1,  1);
7638     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7639     color = getPixelColor(device, 639, 479);
7640     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7641
7642     color = getPixelColor(device, 135, 101);
7643     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7644     color = getPixelColor(device, 140, 101);
7645     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7646     color = getPixelColor(device, 135, 105);
7647     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7648     color = getPixelColor(device, 140, 105);
7649     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7650
7651     color = getPixelColor(device, 135, 376);
7652     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7653     color = getPixelColor(device, 140, 376);
7654     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7655     color = getPixelColor(device, 135, 379);
7656     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7657     color = getPixelColor(device, 140, 379);
7658     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7659
7660     color = getPixelColor(device, 500, 101);
7661     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7662     color = getPixelColor(device, 504, 101);
7663     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7664     color = getPixelColor(device, 500, 105);
7665     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7666     color = getPixelColor(device, 504, 105);
7667     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7668
7669     color = getPixelColor(device, 500, 376);
7670     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7671     color = getPixelColor(device, 504, 376);
7672     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7673     color = getPixelColor(device, 500, 380);
7674     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7675     color = getPixelColor(device, 504, 380);
7676     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7677
7678     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7679     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7680     IDirect3DTexture9_Release(texture);
7681 }
7682
7683 static void vFace_register_test(IDirect3DDevice9 *device)
7684 {
7685     HRESULT hr;
7686     DWORD color;
7687     const DWORD shader_code[] = {
7688         0xffff0300,                                                             /* ps_3_0                     */
7689         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7690         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7691         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7692         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7693         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7694         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7695         0x0000ffff                                                              /* END                        */
7696     };
7697     IDirect3DPixelShader9 *shader;
7698     IDirect3DTexture9 *texture;
7699     IDirect3DSurface9 *surface, *backbuffer;
7700     const float quad[] = {
7701         -1.0,   -1.0,   0.1,
7702          1.0,   -1.0,   0.1,
7703         -1.0,    0.0,   0.1,
7704
7705          1.0,   -1.0,   0.1,
7706          1.0,    0.0,   0.1,
7707         -1.0,    0.0,   0.1,
7708
7709         -1.0,    0.0,   0.1,
7710         -1.0,    1.0,   0.1,
7711          1.0,    0.0,   0.1,
7712
7713          1.0,    0.0,   0.1,
7714         -1.0,    1.0,   0.1,
7715          1.0,    1.0,   0.1,
7716     };
7717     const float blit[] = {
7718          0.0,   -1.0,   0.1,    0.0,    0.0,
7719          1.0,   -1.0,   0.1,    1.0,    0.0,
7720          0.0,    1.0,   0.1,    0.0,    1.0,
7721          1.0,    1.0,   0.1,    1.0,    1.0,
7722     };
7723
7724     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7725     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7726     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7727     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7728     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7729     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7730     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7731     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7732     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7733     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7734     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7735     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7736
7737     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7738     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7739
7740     hr = IDirect3DDevice9_BeginScene(device);
7741     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7742     if(SUCCEEDED(hr)) {
7743         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7744         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7745         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7746         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7747         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7748         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7749         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7750         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7751         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7753         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7754
7755         /* Blit the texture onto the back buffer to make it visible */
7756         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7757         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7758         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7759         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7760         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7761         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7762         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7763         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7764         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7765         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7766
7767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7768         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7769
7770         hr = IDirect3DDevice9_EndScene(device);
7771         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7772     }
7773
7774     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7775     color = getPixelColor(device, 160, 360);
7776     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7777     color = getPixelColor(device, 160, 120);
7778     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7779     color = getPixelColor(device, 480, 360);
7780     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7781     color = getPixelColor(device, 480, 120);
7782     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7783
7784     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7785     IDirect3DDevice9_SetTexture(device, 0, NULL);
7786     IDirect3DPixelShader9_Release(shader);
7787     IDirect3DSurface9_Release(surface);
7788     IDirect3DSurface9_Release(backbuffer);
7789     IDirect3DTexture9_Release(texture);
7790 }
7791
7792 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7793 {
7794     HRESULT hr;
7795     DWORD color;
7796     int i;
7797     D3DCAPS9 caps;
7798     BOOL L6V5U5_supported = FALSE;
7799     IDirect3DTexture9 *tex1, *tex2;
7800     D3DLOCKED_RECT locked_rect;
7801
7802     static const float quad[][7] = {
7803         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7804         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7805         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7806         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7807     };
7808
7809     static const D3DVERTEXELEMENT9 decl_elements[] = {
7810         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7811         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7812         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7813         D3DDECL_END()
7814     };
7815
7816     /* use asymmetric matrix to test loading */
7817     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7818     float scale, offset;
7819
7820     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7821     IDirect3DTexture9           *texture            = NULL;
7822
7823     memset(&caps, 0, sizeof(caps));
7824     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7825     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7826     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7827         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7828         return;
7829     } else {
7830         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7831          * They report that it is not supported, but after that bump mapping works properly. So just test
7832          * if the format is generally supported, and check the BUMPENVMAP flag
7833          */
7834         IDirect3D9 *d3d9;
7835
7836         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7837         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7838                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7839         L6V5U5_supported = SUCCEEDED(hr);
7840         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7841                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7842         IDirect3D9_Release(d3d9);
7843         if(FAILED(hr)) {
7844             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7845             return;
7846         }
7847     }
7848
7849     /* Generate the textures */
7850     generate_bumpmap_textures(device);
7851
7852     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7853     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7854     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7855     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7856     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7857     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7858     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7859     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7860
7861     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7862     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7863     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7864     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7865     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7866     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7867
7868     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7869     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7870     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7871     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7872     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7873     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7874
7875     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7876     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7877
7878     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7879     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7880
7881     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7882     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7883
7884
7885     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7886     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7887     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7888     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7889
7890     hr = IDirect3DDevice9_BeginScene(device);
7891     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7892
7893     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7894     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7895
7896     hr = IDirect3DDevice9_EndScene(device);
7897     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7898
7899     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7900     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7901
7902     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7903      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7904      * But since testing the color match is not the purpose of the test don't be too picky
7905      */
7906     color = getPixelColor(device, 320-32, 240);
7907     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7908     color = getPixelColor(device, 320+32, 240);
7909     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7910     color = getPixelColor(device, 320, 240-32);
7911     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7912     color = getPixelColor(device, 320, 240+32);
7913     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7914     color = getPixelColor(device, 320, 240);
7915     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7916     color = getPixelColor(device, 320+32, 240+32);
7917     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7918     color = getPixelColor(device, 320-32, 240+32);
7919     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7920     color = getPixelColor(device, 320+32, 240-32);
7921     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7922     color = getPixelColor(device, 320-32, 240-32);
7923     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7924
7925     for(i = 0; i < 2; i++) {
7926         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7927         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7928         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7929         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7930         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7931         IDirect3DTexture9_Release(texture); /* To destroy it */
7932     }
7933
7934     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7935         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7936         goto cleanup;
7937     }
7938     if(L6V5U5_supported == FALSE) {
7939         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7940         goto cleanup;
7941     }
7942
7943     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7944     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7945     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7946      * would only make this test more complicated
7947      */
7948     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7949     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7950     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7951     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7952
7953     memset(&locked_rect, 0, sizeof(locked_rect));
7954     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7955     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7956     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7957     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7958     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7959
7960     memset(&locked_rect, 0, sizeof(locked_rect));
7961     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7962     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7963     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7964     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7965     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7966
7967     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7968     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7969     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7970     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7971
7972     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7973     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7974     scale = 2.0;
7975     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7976     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7977     offset = 0.1;
7978     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7979     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7980
7981     hr = IDirect3DDevice9_BeginScene(device);
7982     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7983     if(SUCCEEDED(hr)) {
7984         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7985         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7986         hr = IDirect3DDevice9_EndScene(device);
7987         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7988     }
7989
7990     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7991     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7992     color = getPixelColor(device, 320, 240);
7993     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7994      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7995      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7996      */
7997     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7998
7999     /* Check a result scale factor > 1.0 */
8000     scale = 10;
8001     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8002     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8003     offset = 10;
8004     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8005     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8006
8007     hr = IDirect3DDevice9_BeginScene(device);
8008     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8009     if(SUCCEEDED(hr)) {
8010         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8011         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8012         hr = IDirect3DDevice9_EndScene(device);
8013         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8014     }
8015     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8016     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8017     color = getPixelColor(device, 320, 240);
8018     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8019
8020     /* Check clamping in the scale factor calculation */
8021     scale = 1000;
8022     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8023     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8024     offset = -1;
8025     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8026     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8027
8028     hr = IDirect3DDevice9_BeginScene(device);
8029     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8030     if(SUCCEEDED(hr)) {
8031         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8032         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8033         hr = IDirect3DDevice9_EndScene(device);
8034         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8035     }
8036     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8037     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8038     color = getPixelColor(device, 320, 240);
8039     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8040
8041     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8042     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8043     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8044     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8045
8046     IDirect3DTexture9_Release(tex1);
8047     IDirect3DTexture9_Release(tex2);
8048
8049 cleanup:
8050     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8051     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8052     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8053     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8054
8055     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8056     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8057     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8058 }
8059
8060 static void stencil_cull_test(IDirect3DDevice9 *device) {
8061     HRESULT hr;
8062     IDirect3DSurface9 *depthstencil = NULL;
8063     D3DSURFACE_DESC desc;
8064     float quad1[] = {
8065         -1.0,   -1.0,   0.1,
8066          0.0,   -1.0,   0.1,
8067         -1.0,    0.0,   0.1,
8068          0.0,    0.0,   0.1,
8069     };
8070     float quad2[] = {
8071          0.0,   -1.0,   0.1,
8072          1.0,   -1.0,   0.1,
8073          0.0,    0.0,   0.1,
8074          1.0,    0.0,   0.1,
8075     };
8076     float quad3[] = {
8077         0.0,    0.0,   0.1,
8078         1.0,    0.0,   0.1,
8079         0.0,    1.0,   0.1,
8080         1.0,    1.0,   0.1,
8081     };
8082     float quad4[] = {
8083         -1.0,    0.0,   0.1,
8084          0.0,    0.0,   0.1,
8085         -1.0,    1.0,   0.1,
8086          0.0,    1.0,   0.1,
8087     };
8088     struct vertex painter[] = {
8089        {-1.0,   -1.0,   0.0,    0x00000000},
8090        { 1.0,   -1.0,   0.0,    0x00000000},
8091        {-1.0,    1.0,   0.0,    0x00000000},
8092        { 1.0,    1.0,   0.0,    0x00000000},
8093     };
8094     WORD indices_cw[]  = {0, 1, 3};
8095     WORD indices_ccw[] = {0, 2, 3};
8096     unsigned int i;
8097     DWORD color;
8098
8099     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8100     if(depthstencil == NULL) {
8101         skip("No depth stencil buffer\n");
8102         return;
8103     }
8104     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8105     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8106     IDirect3DSurface9_Release(depthstencil);
8107     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8108         skip("No 4 or 8 bit stencil surface\n");
8109         return;
8110     }
8111
8112     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8113     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8114     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8115
8116     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8117     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8118     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8119     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8120     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8121     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8122     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8123     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8124
8125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8126     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8131
8132     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8133     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8135     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8136
8137     /* First pass: Fill the stencil buffer with some values... */
8138     hr = IDirect3DDevice9_BeginScene(device);
8139     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8140     if(SUCCEEDED(hr))
8141     {
8142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8144         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8145                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8146         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8147                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8148
8149         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8150         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8151         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8152         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8153         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8154                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8155         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8156                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8157
8158         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8159         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8160         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8161                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8162         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8163                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8164
8165         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8166         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8167         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8168                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8169         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8170                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8171
8172         hr = IDirect3DDevice9_EndScene(device);
8173         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8174     }
8175
8176     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8177     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8178     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8179     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8180     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8181     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8182     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8183     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8184     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8185     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8186     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8187     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8188     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8189
8190     /* 2nd pass: Make the stencil values visible */
8191     hr = IDirect3DDevice9_BeginScene(device);
8192     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8193     if(SUCCEEDED(hr))
8194     {
8195         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8196         for(i = 0; i < 16; i++) {
8197             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8198             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8199
8200             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8201             painter[1].diffuse = (i * 16);
8202             painter[2].diffuse = (i * 16);
8203             painter[3].diffuse = (i * 16);
8204             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8205             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8206         }
8207         hr = IDirect3DDevice9_EndScene(device);
8208         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8209     }
8210
8211     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8212     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8213
8214     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8215     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8216
8217     color = getPixelColor(device, 160, 420);
8218     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8219     color = getPixelColor(device, 160, 300);
8220     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8221
8222     color = getPixelColor(device, 480, 420);
8223     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8224     color = getPixelColor(device, 480, 300);
8225     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8226
8227     color = getPixelColor(device, 160, 180);
8228     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8229     color = getPixelColor(device, 160, 60);
8230     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8231
8232     color = getPixelColor(device, 480, 180);
8233     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8234     color = getPixelColor(device, 480, 60);
8235     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8236 }
8237
8238 static void vpos_register_test(IDirect3DDevice9 *device)
8239 {
8240     HRESULT hr;
8241     DWORD color;
8242     const DWORD shader_code[] = {
8243     0xffff0300,                                                             /* ps_3_0                     */
8244     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8245     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8246     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8247     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8248     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8249     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8250     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8251     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8252     0x0000ffff                                                              /* end                        */
8253     };
8254     const DWORD shader_frac_code[] = {
8255     0xffff0300,                                                             /* ps_3_0                     */
8256     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8257     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8258     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8259     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8260     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8261     0x0000ffff                                                              /* end                        */
8262     };
8263     IDirect3DPixelShader9 *shader, *shader_frac;
8264     IDirect3DSurface9 *surface = NULL, *backbuffer;
8265     const float quad[] = {
8266         -1.0,   -1.0,   0.1,    0.0,    0.0,
8267          1.0,   -1.0,   0.1,    1.0,    0.0,
8268         -1.0,    1.0,   0.1,    0.0,    1.0,
8269          1.0,    1.0,   0.1,    1.0,    1.0,
8270     };
8271     D3DLOCKED_RECT lr;
8272     float constant[4] = {1.0, 0.0, 320, 240};
8273     DWORD *pos;
8274
8275     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8276     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8277     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8278     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8279     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8280     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8281     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8282     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8283     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8284     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8285     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8286     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8287
8288     hr = IDirect3DDevice9_BeginScene(device);
8289     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8290     if(SUCCEEDED(hr)) {
8291         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8292         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8293         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8294         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8295         hr = IDirect3DDevice9_EndScene(device);
8296         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8297     }
8298
8299     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8300     /* This has to be pixel exact */
8301     color = getPixelColor(device, 319, 239);
8302     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8303     color = getPixelColor(device, 320, 239);
8304     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8305     color = getPixelColor(device, 319, 240);
8306     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8307     color = getPixelColor(device, 320, 240);
8308     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8309
8310     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8311                                              &surface, NULL);
8312     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8313     hr = IDirect3DDevice9_BeginScene(device);
8314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8315     if(SUCCEEDED(hr)) {
8316         constant[2] = 16; constant[3] = 16;
8317         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8318         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8319         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8320         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8323         hr = IDirect3DDevice9_EndScene(device);
8324         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8325     }
8326     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8327     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8328
8329     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8330     color = *pos & 0x00ffffff;
8331     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8332     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8333     color = *pos & 0x00ffffff;
8334     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8335     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8336     color = *pos & 0x00ffffff;
8337     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8338     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8339     color = *pos & 0x00ffffff;
8340     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8341
8342     hr = IDirect3DSurface9_UnlockRect(surface);
8343     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8344
8345     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8346      * have full control over the multisampling setting inside this test
8347      */
8348     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8349     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8350     hr = IDirect3DDevice9_BeginScene(device);
8351     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8352     if(SUCCEEDED(hr)) {
8353         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8354         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8356         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8357         hr = IDirect3DDevice9_EndScene(device);
8358         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8359     }
8360     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8361     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8362
8363     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8364     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8365
8366     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8367     color = *pos & 0x00ffffff;
8368     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8369
8370     hr = IDirect3DSurface9_UnlockRect(surface);
8371     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8372
8373     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8374     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8375     IDirect3DPixelShader9_Release(shader);
8376     IDirect3DPixelShader9_Release(shader_frac);
8377     if(surface) IDirect3DSurface9_Release(surface);
8378     IDirect3DSurface9_Release(backbuffer);
8379 }
8380
8381 static void pointsize_test(IDirect3DDevice9 *device)
8382 {
8383     HRESULT hr;
8384     D3DCAPS9 caps;
8385     D3DMATRIX matrix;
8386     D3DMATRIX identity;
8387     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8388     DWORD color;
8389     IDirect3DTexture9 *tex1, *tex2;
8390     D3DLOCKED_RECT lr;
8391     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8392                                 0x00000000, 0x00000000};
8393     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8394                                 0x00000000, 0x0000ff00};
8395
8396     const float vertices[] = {
8397         64,     64,     0.1,
8398         128,    64,     0.1,
8399         192,    64,     0.1,
8400         256,    64,     0.1,
8401         320,    64,     0.1,
8402         384,    64,     0.1,
8403         448,    64,     0.1,
8404         512,    64,     0.1,
8405         576,    64,     0.1,
8406     };
8407
8408     /* 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 */
8409     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;
8410     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;
8411     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;
8412     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;
8413
8414     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;
8415     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;
8416     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;
8417     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;
8418
8419     memset(&caps, 0, sizeof(caps));
8420     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8421     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8422     if(caps.MaxPointSize < 32.0) {
8423         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8424         return;
8425     }
8426
8427     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8428     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8429     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8430     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8431     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8432     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8433     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8434     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8435
8436     hr = IDirect3DDevice9_BeginScene(device);
8437     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8438     if(SUCCEEDED(hr)) {
8439         ptsize = 16.0;
8440         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8441         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8442         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8443         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8444
8445         ptsize = 32.0;
8446         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8447         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8448         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8449         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8450
8451         ptsize = 31.5;
8452         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8453         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8454         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8455         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8456
8457         if(caps.MaxPointSize >= 64.0) {
8458             ptsize = 64.0;
8459             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8460             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8461             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8462             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463
8464             ptsize = 63.75;
8465             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8466             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8467             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8468             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8469         }
8470
8471         ptsize = 1.0;
8472         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8473         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8474         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8475         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8476
8477         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8478         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8479         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8480         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8481
8482         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8483         ptsize = 16.0;
8484         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8485         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8486         ptsize = 1.0;
8487         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8488         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8490         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8491
8492         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8493          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8494          */
8495         ptsize = 4.0;
8496         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8497         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8498         ptsize = 16.0;
8499         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8500         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8501         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8502         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8503
8504         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8505         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8506
8507         /* pointsize < pointsize_min < pointsize_max?
8508          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8509          */
8510         ptsize = 1.0;
8511         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8512         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8513         ptsize = 16.0;
8514         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8515         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8516         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8517         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8518
8519         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8520         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8521
8522         hr = IDirect3DDevice9_EndScene(device);
8523         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8524     }
8525     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8526     color = getPixelColor(device, 64-9, 64-9);
8527     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8528     color = getPixelColor(device, 64-8, 64-8);
8529     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8530     color = getPixelColor(device, 64-7, 64-7);
8531     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8532     color = getPixelColor(device, 64+7, 64+7);
8533     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8534     color = getPixelColor(device, 64+8, 64+8);
8535     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8536     color = getPixelColor(device, 64+9, 64+9);
8537     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8538
8539     color = getPixelColor(device, 128-17, 64-17);
8540     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8541     color = getPixelColor(device, 128-16, 64-16);
8542     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8543     color = getPixelColor(device, 128-15, 64-15);
8544     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8545     color = getPixelColor(device, 128+15, 64+15);
8546     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8547     color = getPixelColor(device, 128+16, 64+16);
8548     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8549     color = getPixelColor(device, 128+17, 64+17);
8550     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8551
8552     color = getPixelColor(device, 192-17, 64-17);
8553     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8554     color = getPixelColor(device, 192-16, 64-16);
8555     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8556     color = getPixelColor(device, 192-15, 64-15);
8557     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8558     color = getPixelColor(device, 192+15, 64+15);
8559     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8560     color = getPixelColor(device, 192+16, 64+16);
8561     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8562     color = getPixelColor(device, 192+17, 64+17);
8563     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8564
8565     if(caps.MaxPointSize >= 64.0) {
8566         color = getPixelColor(device, 256-33, 64-33);
8567         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8568         color = getPixelColor(device, 256-32, 64-32);
8569         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8570         color = getPixelColor(device, 256-31, 64-31);
8571         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8572         color = getPixelColor(device, 256+31, 64+31);
8573         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8574         color = getPixelColor(device, 256+32, 64+32);
8575         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8576         color = getPixelColor(device, 256+33, 64+33);
8577         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8578
8579         color = getPixelColor(device, 384-33, 64-33);
8580         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8581         color = getPixelColor(device, 384-32, 64-32);
8582         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8583         color = getPixelColor(device, 384-31, 64-31);
8584         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8585         color = getPixelColor(device, 384+31, 64+31);
8586         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8587         color = getPixelColor(device, 384+32, 64+32);
8588         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8589         color = getPixelColor(device, 384+33, 64+33);
8590         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8591     }
8592
8593     color = getPixelColor(device, 320-1, 64-1);
8594     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8595     color = getPixelColor(device, 320-0, 64-0);
8596     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8597     color = getPixelColor(device, 320+1, 64+1);
8598     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8599
8600     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8601     color = getPixelColor(device, 448-4, 64-4);
8602     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8603     color = getPixelColor(device, 448+4, 64+4);
8604     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8605
8606     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8607     color = getPixelColor(device, 512-4, 64-4);
8608     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8609     color = getPixelColor(device, 512+4, 64+4);
8610     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8611
8612     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8613      * Don't be overly picky - just show that the point is bigger than 1 pixel
8614      */
8615     color = getPixelColor(device, 576-4, 64-4);
8616     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8617     color = getPixelColor(device, 576+4, 64+4);
8618     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8619
8620     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8621      * generates texture coordinates for the point(result: Yes, it does)
8622      *
8623      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8624      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8625      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8626      */
8627     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8628     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8629
8630     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8631     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8632     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8633     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8634     memset(&lr, 0, sizeof(lr));
8635     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8636     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8637     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8638     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8639     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8640     memset(&lr, 0, sizeof(lr));
8641     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8642     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8643     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8644     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8645     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8646     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8648     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8649     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8650     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8651     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8652     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8654     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8656     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8658     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8659     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8660
8661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8662     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8663     ptsize = 32.0;
8664     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8665     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8666
8667     hr = IDirect3DDevice9_BeginScene(device);
8668     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8669     if(SUCCEEDED(hr))
8670     {
8671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8672         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8673         hr = IDirect3DDevice9_EndScene(device);
8674         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8675     }
8676
8677     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8678     color = getPixelColor(device, 64-4, 64-4);
8679     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8680     color = getPixelColor(device, 64-4, 64+4);
8681     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8682     color = getPixelColor(device, 64+4, 64+4);
8683     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8684     color = getPixelColor(device, 64+4, 64-4);
8685     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8686
8687     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8688     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8689     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8690     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8691     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8692     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8693     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8694     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8695     IDirect3DTexture9_Release(tex1);
8696     IDirect3DTexture9_Release(tex2);
8697
8698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8699     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8701     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8702     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8703     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8704 }
8705
8706 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8707 {
8708     HRESULT hr;
8709     IDirect3DPixelShader9 *ps;
8710     IDirect3DTexture9 *tex1, *tex2;
8711     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8712     D3DCAPS9 caps;
8713     DWORD color;
8714     DWORD shader_code[] = {
8715     0xffff0300,                                                             /* ps_3_0             */
8716     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8717     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8718     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8719     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8720     0x0000ffff                                                              /* END                */
8721     };
8722     float quad[] = {
8723        -1.0,   -1.0,    0.1,
8724         1.0,   -1.0,    0.1,
8725        -1.0,    1.0,    0.1,
8726         1.0,    1.0,    0.1,
8727     };
8728     float texquad[] = {
8729        -1.0,   -1.0,    0.1,    0.0,    0.0,
8730         0.0,   -1.0,    0.1,    1.0,    0.0,
8731        -1.0,    1.0,    0.1,    0.0,    1.0,
8732         0.0,    1.0,    0.1,    1.0,    1.0,
8733
8734         0.0,   -1.0,    0.1,    0.0,    0.0,
8735         1.0,   -1.0,    0.1,    1.0,    0.0,
8736         0.0,    1.0,    0.1,    0.0,    1.0,
8737         1.0,    1.0,    0.1,    1.0,    1.0,
8738     };
8739
8740     memset(&caps, 0, sizeof(caps));
8741     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8742     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8743     if(caps.NumSimultaneousRTs < 2) {
8744         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8745         return;
8746     }
8747
8748     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8749     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8750
8751     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8753     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8754     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8755     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8756     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8757
8758     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8759     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8760     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8761     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8762     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8763     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8764
8765     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8766     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8767     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8768     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8769     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8770     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8771     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8772     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8773
8774     hr = IDirect3DDevice9_BeginScene(device);
8775     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8776     if(SUCCEEDED(hr)) {
8777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8778         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8779
8780         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8781         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8782         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8783         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8784         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8785         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8786         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8787         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8788
8789         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8790         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8791         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8792         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8793
8794         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8795         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8797         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8798
8799         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8800         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8801
8802         hr = IDirect3DDevice9_EndScene(device);
8803         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8804     }
8805
8806     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8807     color = getPixelColor(device, 160, 240);
8808     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8809     color = getPixelColor(device, 480, 240);
8810     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8811
8812     IDirect3DPixelShader9_Release(ps);
8813     IDirect3DTexture9_Release(tex1);
8814     IDirect3DTexture9_Release(tex2);
8815     IDirect3DSurface9_Release(surf1);
8816     IDirect3DSurface9_Release(surf2);
8817     IDirect3DSurface9_Release(backbuf);
8818 }
8819
8820 struct formats {
8821     const char *fmtName;
8822     D3DFORMAT textureFormat;
8823     DWORD resultColorBlending;
8824     DWORD resultColorNoBlending;
8825 };
8826
8827 const struct formats test_formats[] = {
8828   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8829   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8830   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8831   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8832   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8833   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8834   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8835   { NULL, 0 }
8836 };
8837
8838 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8839 {
8840     HRESULT hr;
8841     IDirect3DTexture9 *offscreenTexture = NULL;
8842     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8843     IDirect3D9 *d3d = NULL;
8844     DWORD color;
8845     DWORD r0, g0, b0, r1, g1, b1;
8846     int fmt_index;
8847
8848     static const float quad[][5] = {
8849         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8850         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8851         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8852         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8853     };
8854
8855     /* Quad with R=0x10, G=0x20 */
8856     static const struct vertex quad1[] = {
8857         {-1.0f, -1.0f, 0.1f, 0x80102000},
8858         {-1.0f,  1.0f, 0.1f, 0x80102000},
8859         { 1.0f, -1.0f, 0.1f, 0x80102000},
8860         { 1.0f,  1.0f, 0.1f, 0x80102000},
8861     };
8862
8863     /* Quad with R=0x20, G=0x10 */
8864     static const struct vertex quad2[] = {
8865         {-1.0f, -1.0f, 0.1f, 0x80201000},
8866         {-1.0f,  1.0f, 0.1f, 0x80201000},
8867         { 1.0f, -1.0f, 0.1f, 0x80201000},
8868         { 1.0f,  1.0f, 0.1f, 0x80201000},
8869     };
8870
8871     IDirect3DDevice9_GetDirect3D(device, &d3d);
8872
8873     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8874     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8875     if(!backbuffer) {
8876         goto out;
8877     }
8878
8879     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8880     {
8881         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8882         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8883            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8884            continue;
8885         }
8886
8887         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8888         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8889
8890         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8891         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8892         if(!offscreenTexture) {
8893             continue;
8894         }
8895
8896         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8897         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8898         if(!offscreen) {
8899             continue;
8900         }
8901
8902         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8903         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8904
8905         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8906         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8907         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8908         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8909         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8910         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8911         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8912         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8913         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8914         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8915
8916         /* Below we will draw two quads with different colors and try to blend them together.
8917          * The result color is compared with the expected outcome.
8918          */
8919         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8920             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8921             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8922             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8923             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8924
8925             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8926             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8927
8928             /* Draw a quad using color 0x0010200 */
8929             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8930             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8931             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8932             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8933             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8934             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8935
8936             /* Draw a quad using color 0x0020100 */
8937             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8938             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8939             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8940             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8941             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8942             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8943
8944             /* We don't want to blend the result on the backbuffer */
8945             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8946             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8947
8948             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8949             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8950             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8951             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8952             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8953
8954             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8955             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8956
8957             /* This time with the texture */
8958             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8959             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8960
8961             IDirect3DDevice9_EndScene(device);
8962         }
8963         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8964
8965
8966         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8967             /* Compare the color of the center quad with our expectation */
8968             color = getPixelColor(device, 320, 240);
8969             r0 = (color & 0x00ff0000) >> 16;
8970             g0 = (color & 0x0000ff00) >>  8;
8971             b0 = (color & 0x000000ff) >>  0;
8972
8973             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8974             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8975             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8976
8977             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8978                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8979                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8980                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8981         } else {
8982             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8983              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8984              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8985             color = getPixelColor(device, 320, 240);
8986             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);
8987         }
8988
8989         IDirect3DDevice9_SetTexture(device, 0, NULL);
8990         if(offscreenTexture) {
8991             IDirect3DTexture9_Release(offscreenTexture);
8992         }
8993         if(offscreen) {
8994             IDirect3DSurface9_Release(offscreen);
8995         }
8996     }
8997
8998 out:
8999     /* restore things */
9000     if(backbuffer) {
9001         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9002         IDirect3DSurface9_Release(backbuffer);
9003     }
9004 }
9005
9006 static void tssargtemp_test(IDirect3DDevice9 *device)
9007 {
9008     HRESULT hr;
9009     DWORD color;
9010     static const struct vertex quad[] = {
9011         {-1.0,     -1.0,    0.1,    0x00ff0000},
9012         { 1.0,     -1.0,    0.1,    0x00ff0000},
9013         {-1.0,      1.0,    0.1,    0x00ff0000},
9014         { 1.0,      1.0,    0.1,    0x00ff0000}
9015     };
9016     D3DCAPS9 caps;
9017
9018     memset(&caps, 0, sizeof(caps));
9019     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9020     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9021     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9022         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9023         return;
9024     }
9025
9026     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9027     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9028
9029     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9030     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9031     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9032     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9033
9034     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9035     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9036     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9037     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9038     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9039     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9040
9041     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9042     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9043     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9044     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9045     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9046     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9047
9048     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9049     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9050
9051     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9052     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9053     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9054     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9055
9056     hr = IDirect3DDevice9_BeginScene(device);
9057     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9058     if(SUCCEEDED(hr)) {
9059
9060         hr = IDirect3DDevice9_EndScene(device);
9061         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9063         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9064     }
9065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9066     color = getPixelColor(device, 320, 240);
9067     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9068
9069     /* Set stage 1 back to default */
9070     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9071     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9072     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9073     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9074     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9075     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9076     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9077     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9078     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9079     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9080 }
9081
9082 struct testdata
9083 {
9084     DWORD idxVertex; /* number of instances in the first stream */
9085     DWORD idxColor; /* number of instances in the second stream */
9086     DWORD idxInstance; /* should be 1 ?? */
9087     DWORD color1; /* color 1 instance */
9088     DWORD color2; /* color 2 instance */
9089     DWORD color3; /* color 3 instance */
9090     DWORD color4; /* color 4 instance */
9091     WORD strVertex; /* specify which stream to use 0-2*/
9092     WORD strColor;
9093     WORD strInstance;
9094 };
9095
9096 static const struct testdata testcases[]=
9097 {
9098     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9099     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9100     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9101     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9102     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9103     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9104     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9105     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9106     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9107     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9108     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9109     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9110     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9111     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9112     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9113 /*
9114     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9115     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9116 */
9117 };
9118
9119 /* Drawing Indexed Geometry with instances*/
9120 static void stream_test(IDirect3DDevice9 *device)
9121 {
9122     IDirect3DVertexBuffer9 *vb = NULL;
9123     IDirect3DVertexBuffer9 *vb2 = NULL;
9124     IDirect3DVertexBuffer9 *vb3 = NULL;
9125     IDirect3DIndexBuffer9 *ib = NULL;
9126     IDirect3DVertexDeclaration9 *pDecl = NULL;
9127     IDirect3DVertexShader9 *shader = NULL;
9128     HRESULT hr;
9129     BYTE *data;
9130     DWORD color;
9131     DWORD ind;
9132     unsigned i;
9133
9134     const DWORD shader_code[] =
9135     {
9136         0xfffe0101,                                     /* vs_1_1 */
9137         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9138         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9139         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9140         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9141         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9142         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9143         0x0000ffff
9144     };
9145
9146     const float quad[][3] =
9147     {
9148         {-0.5f, -0.5f,  1.1f}, /*0 */
9149         {-0.5f,  0.5f,  1.1f}, /*1 */
9150         { 0.5f, -0.5f,  1.1f}, /*2 */
9151         { 0.5f,  0.5f,  1.1f}, /*3 */
9152     };
9153
9154     const float vertcolor[][4] =
9155     {
9156         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9157         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9158         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9159         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9160     };
9161
9162     /* 4 position for 4 instances */
9163     const float instancepos[][3] =
9164     {
9165         {-0.6f,-0.6f, 0.0f},
9166         { 0.6f,-0.6f, 0.0f},
9167         { 0.6f, 0.6f, 0.0f},
9168         {-0.6f, 0.6f, 0.0f},
9169     };
9170
9171     short indices[] = {0, 1, 2, 1, 2, 3};
9172
9173     D3DVERTEXELEMENT9 decl[] =
9174     {
9175         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9176         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9177         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9178         D3DDECL_END()
9179     };
9180
9181     /* set the default value because it isn't done in wine? */
9182     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9183     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9184
9185     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9186     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9187     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9188
9189     /* check wrong cases */
9190     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9191     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9192     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9193     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9194     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9195     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9196     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9197     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9198     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9199     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9200     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9201     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9202     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9203     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9204     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9205     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9206     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9207     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9208     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9209     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9210
9211     /* set the default value back */
9212     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9213     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9214
9215     /* create all VertexBuffers*/
9216     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9217     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9218     if(!vb) {
9219         skip("Failed to create a vertex buffer\n");
9220         return;
9221     }
9222     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9223     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9224     if(!vb2) {
9225         skip("Failed to create a vertex buffer\n");
9226         goto out;
9227     }
9228     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9229     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9230     if(!vb3) {
9231         skip("Failed to create a vertex buffer\n");
9232         goto out;
9233     }
9234
9235     /* create IndexBuffer*/
9236     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9237     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9238     if(!ib) {
9239         skip("Failed to create a index buffer\n");
9240         goto out;
9241     }
9242
9243     /* copy all Buffers (Vertex + Index)*/
9244     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9245     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9246     memcpy(data, quad, sizeof(quad));
9247     hr = IDirect3DVertexBuffer9_Unlock(vb);
9248     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9249     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9250     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9251     memcpy(data, vertcolor, sizeof(vertcolor));
9252     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9253     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9254     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9255     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9256     memcpy(data, instancepos, sizeof(instancepos));
9257     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9258     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9259     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9260     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9261     memcpy(data, indices, sizeof(indices));
9262     hr = IDirect3DIndexBuffer9_Unlock(ib);
9263     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9264
9265     /* create VertexShader */
9266     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9267     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9268     if(!shader) {
9269         skip("Failed to create a vetex shader\n");
9270         goto out;
9271     }
9272
9273     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9274     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9275
9276     hr = IDirect3DDevice9_SetIndices(device, ib);
9277     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9278
9279     /* run all tests */
9280     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9281     {
9282         struct testdata act = testcases[i];
9283         decl[0].Stream = act.strVertex;
9284         decl[1].Stream = act.strColor;
9285         decl[2].Stream = act.strInstance;
9286         /* create VertexDeclarations */
9287         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9288         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9289
9290         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9291         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9292
9293         hr = IDirect3DDevice9_BeginScene(device);
9294         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9295         if(SUCCEEDED(hr))
9296         {
9297             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9298             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9299
9300             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9301             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9302             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9303             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9304
9305             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9306             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9307             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9308             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9309
9310             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9311             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9312             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9313             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9314
9315             /* don't know if this is right (1*3 and 4*1)*/
9316             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9317             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9318             hr = IDirect3DDevice9_EndScene(device);
9319             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9320
9321             /* set all StreamSource && StreamSourceFreq back to default */
9322             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9323             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9324             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9325             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9326             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9327             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9328             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9329             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9330             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9331             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9332             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9333             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9334         }
9335
9336         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9337         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9338
9339         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9340         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9341
9342         color = getPixelColor(device, 160, 360);
9343         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9344         color = getPixelColor(device, 480, 360);
9345         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9346         color = getPixelColor(device, 480, 120);
9347         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9348         color = getPixelColor(device, 160, 120);
9349         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9350     }
9351
9352     hr = IDirect3DDevice9_SetIndices(device, NULL);
9353     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9354
9355 out:
9356     if(vb) IDirect3DVertexBuffer9_Release(vb);
9357     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9358     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9359     if(ib)IDirect3DIndexBuffer9_Release(ib);
9360     if(shader)IDirect3DVertexShader9_Release(shader);
9361 }
9362
9363 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9364     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9365     IDirect3DTexture9 *dsttex = NULL;
9366     HRESULT hr;
9367     DWORD color;
9368     D3DRECT r1 = {0,  0,  50,  50 };
9369     D3DRECT r2 = {50, 0,  100, 50 };
9370     D3DRECT r3 = {50, 50, 100, 100};
9371     D3DRECT r4 = {0,  50,  50, 100};
9372     const float quad[] = {
9373         -1.0,   -1.0,   0.1,    0.0,    0.0,
9374          1.0,   -1.0,   0.1,    1.0,    0.0,
9375         -1.0,    1.0,   0.1,    0.0,    1.0,
9376          1.0,    1.0,   0.1,    1.0,    1.0,
9377     };
9378
9379     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9380     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9381
9382     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9383     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9384     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9385     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9386
9387     if(!src || !dsttex) {
9388         skip("One or more test resources could not be created\n");
9389         goto cleanup;
9390     }
9391
9392     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9393     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9394
9395     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9396     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9397
9398     /* Clear the StretchRect destination for debugging */
9399     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9400     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9401     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9402     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9403
9404     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9405     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9406
9407     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9408     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9409     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9410     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9411     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9412     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9413     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9414     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9415
9416     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9417      * the target -> texture GL blit path
9418      */
9419     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9420     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9421     IDirect3DSurface9_Release(dst);
9422
9423     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9425
9426     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9428     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9429     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9430     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9431     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9432     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9433     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9434
9435     hr = IDirect3DDevice9_BeginScene(device);
9436     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9437     if(SUCCEEDED(hr)) {
9438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9439         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9440         hr = IDirect3DDevice9_EndScene(device);
9441         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9442     }
9443
9444     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9445     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9446     color = getPixelColor(device, 160, 360);
9447     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9448     color = getPixelColor(device, 480, 360);
9449     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9450     color = getPixelColor(device, 480, 120);
9451     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9452     color = getPixelColor(device, 160, 120);
9453     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9454
9455     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9456     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9457     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9458     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9459
9460 cleanup:
9461     if(src) IDirect3DSurface9_Release(src);
9462     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9463     if(dsttex) IDirect3DTexture9_Release(dsttex);
9464 }
9465
9466 static void texop_test(IDirect3DDevice9 *device)
9467 {
9468     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9469     IDirect3DTexture9 *texture = NULL;
9470     D3DLOCKED_RECT locked_rect;
9471     D3DCOLOR color;
9472     D3DCAPS9 caps;
9473     HRESULT hr;
9474     unsigned i;
9475
9476     static const struct {
9477         float x, y, z;
9478         float s, t;
9479         D3DCOLOR diffuse;
9480     } quad[] = {
9481         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9482         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9483         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9484         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9485     };
9486
9487     static const D3DVERTEXELEMENT9 decl_elements[] = {
9488         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9489         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9490         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9491         D3DDECL_END()
9492     };
9493
9494     static const struct {
9495         D3DTEXTUREOP op;
9496         const char *name;
9497         DWORD caps_flag;
9498         D3DCOLOR result;
9499     } test_data[] = {
9500         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9501         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9502         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9503         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9504         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9505         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9506         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9507         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9508         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9509         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9510         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9511         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9512         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9513         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9514         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9515         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9516         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9517         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9518         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9519         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9520         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9521         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9522         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9523     };
9524
9525     memset(&caps, 0, sizeof(caps));
9526     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9527     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9528
9529     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9530     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9531     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9532     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9533
9534     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9535     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9536     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9537     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9538     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9539     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9540     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9541     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9542     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9543
9544     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9545     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9546     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9547     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9548     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9549     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9550
9551     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9552     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9553
9554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9555     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9557     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9559     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9560
9561     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9562     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9563
9564     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9565     {
9566         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9567         {
9568             skip("tex operation %s not supported\n", test_data[i].name);
9569             continue;
9570         }
9571
9572         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9573         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9574
9575         hr = IDirect3DDevice9_BeginScene(device);
9576         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9577
9578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9579         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9580
9581         hr = IDirect3DDevice9_EndScene(device);
9582         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9583
9584         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9585         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9586
9587         color = getPixelColor(device, 320, 240);
9588         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9589                 test_data[i].name, color, test_data[i].result);
9590     }
9591
9592     if (texture) IDirect3DTexture9_Release(texture);
9593     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9594 }
9595
9596 static void yuv_color_test(IDirect3DDevice9 *device) {
9597     HRESULT hr;
9598     IDirect3DSurface9 *surface = NULL, *target = NULL;
9599     unsigned int fmt, i;
9600     D3DFORMAT format;
9601     const char *fmt_string;
9602     D3DLOCKED_RECT lr;
9603     IDirect3D9 *d3d;
9604     HRESULT color;
9605     DWORD ref_color_left, ref_color_right;
9606
9607     struct {
9608         DWORD in;           /* The input color */
9609         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9610         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9611         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9612         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9613     } test_data[] = {
9614     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9615      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9616      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9617      * that
9618      */
9619       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9620       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9621       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9622       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9623       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9624       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9625       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9626       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9627       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9628       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9629       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9630       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9631       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9632       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9633
9634       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9635       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9636       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9637       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9638     };
9639
9640     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9641     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9642     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9643     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9644
9645     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9646     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9647
9648     for(fmt = 0; fmt < 2; fmt++) {
9649         if(fmt == 0) {
9650             format = D3DFMT_UYVY;
9651             fmt_string = "D3DFMT_UYVY";
9652         } else {
9653             format = D3DFMT_YUY2;
9654             fmt_string = "D3DFMT_YUY2";
9655         }
9656
9657         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9658                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9659                        */
9660         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9661                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9662             skip("%s is not supported\n", fmt_string);
9663             continue;
9664         }
9665
9666         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9667         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9668         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9669
9670         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9671             if(fmt == 0) {
9672                 ref_color_left = test_data[i].uyvy_left;
9673                 ref_color_right = test_data[i].uyvy_right;
9674             } else {
9675                 ref_color_left = test_data[i].yuy2_left;
9676                 ref_color_right = test_data[i].yuy2_right;
9677             }
9678
9679             memset(&lr, 0, sizeof(lr));
9680             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9681             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9682             *((DWORD *) lr.pBits) = test_data[i].in;
9683             hr = IDirect3DSurface9_UnlockRect(surface);
9684             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9685
9686             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9687             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9688             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9689             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9690             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9691             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9692
9693             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9694              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9695              * want to add tests for the filtered pixels as well.
9696              *
9697              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9698              * differently, so we need a max diff of 16
9699              */
9700             color = getPixelColor(device, 40, 240);
9701             ok(color_match(color, ref_color_left, 16),
9702                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9703                test_data[i].in, color, ref_color_left, fmt_string);
9704             color = getPixelColor(device, 600, 240);
9705             ok(color_match(color, ref_color_right, 16),
9706                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9707                test_data[i].in, color, ref_color_right, fmt_string);
9708         }
9709         IDirect3DSurface9_Release(surface);
9710     }
9711     IDirect3DSurface9_Release(target);
9712     IDirect3D9_Release(d3d);
9713 }
9714
9715 static void texop_range_test(IDirect3DDevice9 *device)
9716 {
9717     static const struct {
9718         float x, y, z;
9719         D3DCOLOR diffuse;
9720     } quad[] = {
9721         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9722         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9723         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9724         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9725     };
9726     HRESULT hr;
9727     IDirect3DTexture9 *texture;
9728     D3DLOCKED_RECT locked_rect;
9729     D3DCAPS9 caps;
9730     DWORD color;
9731
9732     /* We need ADD and SUBTRACT operations */
9733     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9734     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9735     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9736         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9737     }
9738     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9739         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9740     }
9741
9742     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9743     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9744     /* Stage 1: result = diffuse(=1.0) + diffuse
9745      * stage 2: result = result - tfactor(= 0.5)
9746      */
9747     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9748     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9749     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9750     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9751     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9752     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9753     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9754     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9755     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9756     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9757     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9758     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9759     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9760     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9761
9762     hr = IDirect3DDevice9_BeginScene(device);
9763     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9764     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9765     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9766     hr = IDirect3DDevice9_EndScene(device);
9767     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9768     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9769     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9770
9771     color = getPixelColor(device, 320, 240);
9772     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9773        color);
9774
9775     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9776     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9777     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9778     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9779     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9780     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9781     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9782     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9783     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9784
9785     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9786      * stage 2: result = result + diffuse(1.0)
9787      */
9788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9789     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9790     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9791     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9793     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9795     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9796     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9797     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9798     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9799     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9800     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9801     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9802
9803     hr = IDirect3DDevice9_BeginScene(device);
9804     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9805     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9806     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9807     hr = IDirect3DDevice9_EndScene(device);
9808     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9809     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9810     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9811
9812     color = getPixelColor(device, 320, 240);
9813     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9814        color);
9815
9816     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9817     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9818     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9819     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9820     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9821     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9822     IDirect3DTexture9_Release(texture);
9823 }
9824
9825 static void alphareplicate_test(IDirect3DDevice9 *device) {
9826     struct vertex quad[] = {
9827         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9828         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9829         { -1.0,     1.0,    0.1,    0x80ff00ff },
9830         {  1.0,     1.0,    0.1,    0x80ff00ff },
9831     };
9832     HRESULT hr;
9833     DWORD color;
9834
9835     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9836     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9837
9838     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9839     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9840
9841     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9842     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9843     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9844     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9845
9846     hr = IDirect3DDevice9_BeginScene(device);
9847     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9848     if(SUCCEEDED(hr)) {
9849         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9850         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9851         hr = IDirect3DDevice9_EndScene(device);
9852         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9853     }
9854
9855     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9856     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9857
9858     color = getPixelColor(device, 320, 240);
9859     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9860        color);
9861
9862     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9863     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9864
9865 }
9866
9867 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9868     HRESULT hr;
9869     D3DCAPS9 caps;
9870     DWORD color;
9871     struct vertex quad[] = {
9872         { -1.0,    -1.0,    0.1,    0x408080c0 },
9873         {  1.0,    -1.0,    0.1,    0x408080c0 },
9874         { -1.0,     1.0,    0.1,    0x408080c0 },
9875         {  1.0,     1.0,    0.1,    0x408080c0 },
9876     };
9877
9878     memset(&caps, 0, sizeof(caps));
9879     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9880     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9881     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9882         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9883         return;
9884     }
9885
9886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9887     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9888
9889     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9890     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9891
9892     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9893      * mov r0.a, diffuse.a
9894      * mov r0, r0.a
9895      *
9896      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9897      * 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
9898      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9899      */
9900     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9901     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9902     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9903     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9905     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9906     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9907     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9908     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9909     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9910     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9911     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9912     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9913     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9914     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9915     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9916     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9917     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9918
9919     hr = IDirect3DDevice9_BeginScene(device);
9920     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9921     if(SUCCEEDED(hr)) {
9922         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9923         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9924         hr = IDirect3DDevice9_EndScene(device);
9925         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9926     }
9927
9928     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9929     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9930
9931     color = getPixelColor(device, 320, 240);
9932     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9933        color);
9934
9935     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9936     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9937     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9938     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9939     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9940     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9941 }
9942
9943 static void zwriteenable_test(IDirect3DDevice9 *device) {
9944     HRESULT hr;
9945     DWORD color;
9946     struct vertex quad1[] = {
9947         { -1.0,  -1.0,  0.1,    0x00ff0000},
9948         { -1.0,   1.0,  0.1,    0x00ff0000},
9949         {  1.0,  -1.0,  0.1,    0x00ff0000},
9950         {  1.0,   1.0,  0.1,    0x00ff0000},
9951     };
9952     struct vertex quad2[] = {
9953         { -1.0,  -1.0,  0.9,    0x0000ff00},
9954         { -1.0,   1.0,  0.9,    0x0000ff00},
9955         {  1.0,  -1.0,  0.9,    0x0000ff00},
9956         {  1.0,   1.0,  0.9,    0x0000ff00},
9957     };
9958
9959     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9961
9962     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9964     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9965     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9966     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9967     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9969     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9970
9971     hr = IDirect3DDevice9_BeginScene(device);
9972     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9973     if(SUCCEEDED(hr)) {
9974         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9975          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9976          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9977          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9978          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9979          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9980          */
9981         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9982         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9983         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9984         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9985         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9986         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9987
9988         hr = IDirect3DDevice9_EndScene(device);
9989         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9990     }
9991
9992     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9993     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9994     color = getPixelColor(device, 320, 240);
9995     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9996        color);
9997
9998     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9999     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10000 }
10001
10002 static void alphatest_test(IDirect3DDevice9 *device) {
10003 #define ALPHATEST_PASSED 0x0000ff00
10004 #define ALPHATEST_FAILED 0x00ff0000
10005     struct {
10006         D3DCMPFUNC  func;
10007         DWORD       color_less;
10008         DWORD       color_equal;
10009         DWORD       color_greater;
10010     } testdata[] = {
10011         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10012         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10013         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10014         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10015         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10016         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10017         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10018         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10019     };
10020     unsigned int i, j;
10021     HRESULT hr;
10022     DWORD color;
10023     struct vertex quad[] = {
10024         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10025         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10026         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10027         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10028     };
10029     D3DCAPS9 caps;
10030
10031     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10032     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10033     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10034     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10035
10036     for(j = 0; j < 2; j++) {
10037         if(j == 1) {
10038             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10039              * the alpha test either for performance reasons(floating point RTs) or to work
10040              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10041              * codepath for ffp and shader in this case, and the test should cover both
10042              */
10043             IDirect3DPixelShader9 *ps;
10044             DWORD shader_code[] = {
10045                 0xffff0101,                                 /* ps_1_1           */
10046                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10047                 0x0000ffff                                  /* end              */
10048             };
10049             memset(&caps, 0, sizeof(caps));
10050             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10051             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10052             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10053                 break;
10054             }
10055
10056             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10057             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10058             IDirect3DDevice9_SetPixelShader(device, ps);
10059             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10060             IDirect3DPixelShader9_Release(ps);
10061         }
10062
10063         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10064             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10065             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10066
10067             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10068             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10069             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10070             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10071             hr = IDirect3DDevice9_BeginScene(device);
10072             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10073             if(SUCCEEDED(hr)) {
10074                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10075                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10076                 hr = IDirect3DDevice9_EndScene(device);
10077                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10078             }
10079             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10080             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10081             color = getPixelColor(device, 320, 240);
10082             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10083             color, testdata[i].color_less, testdata[i].func);
10084
10085             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10086             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10087             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10088             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10089             hr = IDirect3DDevice9_BeginScene(device);
10090             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10091             if(SUCCEEDED(hr)) {
10092                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10093                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10094                 hr = IDirect3DDevice9_EndScene(device);
10095                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10096             }
10097             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10098             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10099             color = getPixelColor(device, 320, 240);
10100             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10101             color, testdata[i].color_equal, testdata[i].func);
10102
10103             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10104             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10105             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10106             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10107             hr = IDirect3DDevice9_BeginScene(device);
10108             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10109             if(SUCCEEDED(hr)) {
10110                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10111                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10112                 hr = IDirect3DDevice9_EndScene(device);
10113                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10114             }
10115             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10116             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10117             color = getPixelColor(device, 320, 240);
10118             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10119             color, testdata[i].color_greater, testdata[i].func);
10120         }
10121     }
10122
10123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10124     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10125     IDirect3DDevice9_SetPixelShader(device, NULL);
10126     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10127 }
10128
10129 static void sincos_test(IDirect3DDevice9 *device) {
10130     const DWORD sin_shader_code[] = {
10131         0xfffe0200,                                                                 /* vs_2_0                       */
10132         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10133         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10134         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10135         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10136         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10137         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10138         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10139         0x0000ffff                                                                  /* end                          */
10140     };
10141     const DWORD cos_shader_code[] = {
10142         0xfffe0200,                                                                 /* vs_2_0                       */
10143         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10144         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10145         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10146         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10147         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10148         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10149         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10150         0x0000ffff                                                                  /* end                          */
10151     };
10152     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10153     HRESULT hr;
10154     struct {
10155         float x, y, z;
10156     } data[1280];
10157     unsigned int i;
10158     float sincosc1[4] = {D3DSINCOSCONST1};
10159     float sincosc2[4] = {D3DSINCOSCONST2};
10160
10161     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10162     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10163
10164     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10165     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10166     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10167     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10168     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10169     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10170     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10171     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10172     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10173     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10174
10175     /* Generate a point from -1 to 1 every 0.5 pixels */
10176     for(i = 0; i < 1280; i++) {
10177         data[i].x = (-640.0 + i) / 640.0;
10178         data[i].y = 0.0;
10179         data[i].z = 0.1;
10180     }
10181
10182     hr = IDirect3DDevice9_BeginScene(device);
10183     if(SUCCEEDED(hr)) {
10184         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10185         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10186         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10187         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10188
10189         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10190         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10191         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10192         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10193
10194         hr = IDirect3DDevice9_EndScene(device);
10195         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10196     }
10197     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10198     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10199
10200     IDirect3DDevice9_SetVertexShader(device, NULL);
10201     IDirect3DVertexShader9_Release(sin_shader);
10202     IDirect3DVertexShader9_Release(cos_shader);
10203 }
10204
10205 static void loop_index_test(IDirect3DDevice9 *device) {
10206     const DWORD shader_code[] = {
10207         0xfffe0200,                                                 /* vs_2_0                   */
10208         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10209         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10210         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10211         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10212         0x0000001d,                                                 /* endloop                  */
10213         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10214         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10215         0x0000ffff                                                  /* END                      */
10216     };
10217     IDirect3DVertexShader9 *shader;
10218     HRESULT hr;
10219     DWORD color;
10220     const float quad[] = {
10221         -1.0,   -1.0,   0.1,
10222          1.0,   -1.0,   0.1,
10223         -1.0,    1.0,   0.1,
10224          1.0,    1.0,   0.1
10225     };
10226     const float zero[4] = {0, 0, 0, 0};
10227     const float one[4] = {1, 1, 1, 1};
10228     int i0[4] = {2, 10, -3, 0};
10229     float values[4];
10230
10231     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10232     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10233     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10234     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10235     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10236     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10237     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10238     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10239
10240     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10241     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10242     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10243     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10244     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10245     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10246     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10247     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10248     values[0] = 1.0;
10249     values[1] = 1.0;
10250     values[2] = 0.0;
10251     values[3] = 0.0;
10252     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10253     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10254     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10255     values[0] = -1.0;
10256     values[1] = 0.0;
10257     values[2] = 0.0;
10258     values[3] = 0.0;
10259     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10260     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10261     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10262     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10263     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10264
10265     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10266
10267     hr = IDirect3DDevice9_BeginScene(device);
10268     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10269     if(SUCCEEDED(hr))
10270     {
10271         trace("going to draw index\n");
10272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10274         hr = IDirect3DDevice9_EndScene(device);
10275         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10276     }
10277     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10279
10280     color = getPixelColor(device, 320, 240);
10281     ok(color_match(color, 0x0000ff00, 1),
10282        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10283
10284     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10285     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10286     IDirect3DVertexShader9_Release(shader);
10287 }
10288
10289 static void sgn_test(IDirect3DDevice9 *device) {
10290     const DWORD shader_code[] = {
10291         0xfffe0200,                                                             /* vs_2_0                       */
10292         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10293         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10294         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10295         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10296         0x02000022, 0x800f0000, 0xa0e40000,                                     /* sgn r0, c0                   */
10297         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10298         0x0000ffff                                                              /* end                          */
10299     };
10300     IDirect3DVertexShader9 *shader;
10301     HRESULT hr;
10302     DWORD color;
10303     const float quad[] = {
10304         -1.0,   -1.0,   0.1,
10305          1.0,   -1.0,   0.1,
10306         -1.0,    1.0,   0.1,
10307          1.0,    1.0,   0.1
10308     };
10309
10310     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10311     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10312     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10313     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10314     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10315     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10316     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10317     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10318
10319     hr = IDirect3DDevice9_BeginScene(device);
10320     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10321     if(SUCCEEDED(hr))
10322     {
10323         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10324         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10325         hr = IDirect3DDevice9_EndScene(device);
10326         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10327     }
10328     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10329     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10330
10331     color = getPixelColor(device, 320, 240);
10332     ok(color_match(color, 0x008000ff, 1),
10333        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10334
10335     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10336     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10337     IDirect3DVertexShader9_Release(shader);
10338 }
10339
10340 START_TEST(visual)
10341 {
10342     IDirect3DDevice9 *device_ptr;
10343     D3DCAPS9 caps;
10344     HRESULT hr;
10345     DWORD color;
10346
10347     d3d9_handle = LoadLibraryA("d3d9.dll");
10348     if (!d3d9_handle)
10349     {
10350         skip("Could not load d3d9.dll\n");
10351         return;
10352     }
10353
10354     device_ptr = init_d3d9();
10355     if (!device_ptr)
10356     {
10357         skip("Creating the device failed\n");
10358         return;
10359     }
10360
10361     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10362
10363     /* Check for the reliability of the returned data */
10364     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10365     if(FAILED(hr))
10366     {
10367         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10368         goto cleanup;
10369     }
10370     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10371
10372     color = getPixelColor(device_ptr, 1, 1);
10373     if(color !=0x00ff0000)
10374     {
10375         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10376         goto cleanup;
10377     }
10378
10379     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10380     if(FAILED(hr))
10381     {
10382         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10383         goto cleanup;
10384     }
10385     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10386
10387     color = getPixelColor(device_ptr, 639, 479);
10388     if(color != 0x0000ddee)
10389     {
10390         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10391         goto cleanup;
10392     }
10393
10394     /* Now execute the real tests */
10395     stretchrect_test(device_ptr);
10396     lighting_test(device_ptr);
10397     clear_test(device_ptr);
10398     fog_test(device_ptr);
10399     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10400     {
10401         test_cube_wrap(device_ptr);
10402     } else {
10403         skip("No cube texture support\n");
10404     }
10405     z_range_test(device_ptr);
10406     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10407     {
10408         maxmip_test(device_ptr);
10409     }
10410     else
10411     {
10412         skip("No mipmap support\n");
10413     }
10414     offscreen_test(device_ptr);
10415     alpha_test(device_ptr);
10416     shademode_test(device_ptr);
10417     srgbtexture_test(device_ptr);
10418     release_buffer_test(device_ptr);
10419     float_texture_test(device_ptr);
10420     g16r16_texture_test(device_ptr);
10421     pixelshader_blending_test(device_ptr);
10422     texture_transform_flags_test(device_ptr);
10423     autogen_mipmap_test(device_ptr);
10424     fixed_function_decl_test(device_ptr);
10425     conditional_np2_repeat_test(device_ptr);
10426     fixed_function_bumpmap_test(device_ptr);
10427     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10428         stencil_cull_test(device_ptr);
10429     } else {
10430         skip("No two sided stencil support\n");
10431     }
10432     pointsize_test(device_ptr);
10433     tssargtemp_test(device_ptr);
10434     np2_stretch_rect_test(device_ptr);
10435     yuv_color_test(device_ptr);
10436     zwriteenable_test(device_ptr);
10437     alphatest_test(device_ptr);
10438
10439     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10440     {
10441         test_constant_clamp_vs(device_ptr);
10442         test_compare_instructions(device_ptr);
10443     }
10444     else skip("No vs_1_1 support\n");
10445
10446     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10447     {
10448         test_mova(device_ptr);
10449         loop_index_test(device_ptr);
10450         sincos_test(device_ptr);
10451         sgn_test(device_ptr);
10452         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10453             test_vshader_input(device_ptr);
10454             test_vshader_float16(device_ptr);
10455             stream_test(device_ptr);
10456         } else {
10457             skip("No vs_3_0 support\n");
10458         }
10459     }
10460     else skip("No vs_2_0 support\n");
10461
10462     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10463     {
10464         fog_with_shader_test(device_ptr);
10465         fog_srgbwrite_test(device_ptr);
10466     }
10467     else skip("No vs_1_1 and ps_1_1 support\n");
10468
10469     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10470     {
10471         texbem_test(device_ptr);
10472         texdepth_test(device_ptr);
10473         texkill_test(device_ptr);
10474         x8l8v8u8_test(device_ptr);
10475         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10476             constant_clamp_ps_test(device_ptr);
10477             cnd_test(device_ptr);
10478             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10479                 dp2add_ps_test(device_ptr);
10480                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10481                     nested_loop_test(device_ptr);
10482                     fixed_function_varying_test(device_ptr);
10483                     vFace_register_test(device_ptr);
10484                     vpos_register_test(device_ptr);
10485                     multiple_rendertargets_test(device_ptr);
10486                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10487                         vshader_version_varying_test(device_ptr);
10488                         pshader_version_varying_test(device_ptr);
10489                     } else {
10490                         skip("No vs_3_0 support\n");
10491                     }
10492                 } else {
10493                     skip("No ps_3_0 support\n");
10494                 }
10495             } else {
10496                 skip("No ps_2_0 support\n");
10497             }
10498         }
10499     }
10500     else skip("No ps_1_1 support\n");
10501
10502     texop_test(device_ptr);
10503     texop_range_test(device_ptr);
10504     alphareplicate_test(device_ptr);
10505     dp3_alpha_test(device_ptr);
10506
10507 cleanup:
10508     if(device_ptr) {
10509         D3DPRESENT_PARAMETERS present_parameters;
10510         IDirect3DSwapChain9 *swapchain;
10511         ULONG ref;
10512
10513         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10514         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10515         DestroyWindow(present_parameters.hDeviceWindow);
10516         IDirect3DSwapChain9_Release(swapchain);
10517         ref = IDirect3DDevice9_Release(device_ptr);
10518         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10519     }
10520 }