comctl32/listview: Free ID array when removing all items.
[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         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
901
902         hr = IDirect3DDevice9_EndScene(device);
903         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
904     }
905     else
906     {
907         ok(FALSE, "BeginScene failed\n");
908     }
909
910     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
911     color = getPixelColor(device, 160, 360);
912     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
913     color = getPixelColor(device, 160, 120);
914     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
915     color = getPixelColor(device, 480, 120);
916     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
917     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
918     {
919         color = getPixelColor(device, 480, 360);
920         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
921     }
922     else
923     {
924         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
925          * The settings above result in no fogging with vertex fog
926          */
927         color = getPixelColor(device, 480, 120);
928         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
929         trace("Info: Table fog not supported by this device\n");
930     }
931
932     /* Now test the special case fogstart == fogend */
933     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
934     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
935
936     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
937     {
938         start = 512;
939         end = 512;
940         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
941         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
942         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
943         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
944
945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
946         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
947         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
948         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
949         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
950         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
951
952         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
953          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
954          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
955          * The third transformed quad remains unfogged because the fogcoords are read from the specular
956          * color and has fixed fogstart and fogend.
957          */
958         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
959                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
960                 sizeof(unstransformed_1[0]));
961         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
962         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
964                 sizeof(unstransformed_1[0]));
965         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
966
967         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
968         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
969         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
970         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
971                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
972                 sizeof(transformed_1[0]));
973         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
974
975         hr = IDirect3DDevice9_EndScene(device);
976         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
977     }
978     else
979     {
980         ok(FALSE, "BeginScene failed\n");
981     }
982     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
983     color = getPixelColor(device, 160, 360);
984     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
985     color = getPixelColor(device, 160, 120);
986     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
987     color = getPixelColor(device, 480, 120);
988     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
989
990     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
991      * but without shaders it seems to work everywhere
992      */
993     end = 0.2;
994     start = 0.8;
995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
996     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
998     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
999     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1000     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1001
1002     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1003      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1004      * so skip this for now
1005      */
1006     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1007         const char *mode = (i ? "table" : "vertex");
1008         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1009         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1010         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1011         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1012         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1013         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1014         hr = IDirect3DDevice9_BeginScene(device);
1015         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1016         if(SUCCEEDED(hr)) {
1017             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1018                                 4,  5,  6,  6,  7, 4,
1019                                 8,  9, 10, 10, 11, 8,
1020                             12, 13, 14, 14, 15, 12};
1021
1022             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1023                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1024                     sizeof(rev_fog_quads[0]));
1025             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1026
1027             hr = IDirect3DDevice9_EndScene(device);
1028             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1029         }
1030         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1031         color = getPixelColor(device, 160, 360);
1032         ok(color_match(color, 0x0000ff00, 1),
1033                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1034
1035         color = getPixelColor(device, 160, 120);
1036         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1037                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1038
1039         color = getPixelColor(device, 480, 120);
1040         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1041                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1042
1043         color = getPixelColor(device, 480, 360);
1044         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1045
1046         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1047             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1048             break;
1049         }
1050     }
1051     /* Turn off the fog master switch to avoid confusing other tests */
1052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1053     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1054     start = 0.0;
1055     end = 1.0;
1056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1057     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1059     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1061     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1063     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1064 }
1065
1066 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1067  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1068  * regardless of the actual addressing mode set. */
1069 static void test_cube_wrap(IDirect3DDevice9 *device)
1070 {
1071     static const float quad[][6] = {
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         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1075         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1076     };
1077
1078     static const D3DVERTEXELEMENT9 decl_elements[] = {
1079         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1080         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1081         D3DDECL_END()
1082     };
1083
1084     static const struct {
1085         D3DTEXTUREADDRESS mode;
1086         const char *name;
1087     } address_modes[] = {
1088         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1089         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1090         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1091         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1092         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1093     };
1094
1095     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1096     IDirect3DCubeTexture9 *texture = NULL;
1097     IDirect3DSurface9 *surface = NULL;
1098     D3DLOCKED_RECT locked_rect;
1099     HRESULT hr;
1100     UINT x;
1101     INT y, face;
1102
1103     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1104     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1105     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1106     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1107
1108     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1109             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1110     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1111
1112     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1113     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1114
1115     for (y = 0; y < 128; ++y)
1116     {
1117         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1118         for (x = 0; x < 64; ++x)
1119         {
1120             *ptr++ = 0xffff0000;
1121         }
1122         for (x = 64; x < 128; ++x)
1123         {
1124             *ptr++ = 0xff0000ff;
1125         }
1126     }
1127
1128     hr = IDirect3DSurface9_UnlockRect(surface);
1129     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1130
1131     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1132             D3DPOOL_DEFAULT, &texture, NULL);
1133     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1134
1135     /* Create cube faces */
1136     for (face = 0; face < 6; ++face)
1137     {
1138         IDirect3DSurface9 *face_surface = NULL;
1139
1140         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1141         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1142
1143         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1144         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1145
1146         IDirect3DSurface9_Release(face_surface);
1147     }
1148
1149     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1150     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1151
1152     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1153     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1154     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1155     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1156     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1157     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1158
1159     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1160     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1161
1162     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1163     {
1164         DWORD color;
1165
1166         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1167         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1168         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1169         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1170
1171         hr = IDirect3DDevice9_BeginScene(device);
1172         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1173
1174         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1175         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1176
1177         hr = IDirect3DDevice9_EndScene(device);
1178         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1179
1180         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1181         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1182
1183         /* Due to the nature of this test, we sample essentially at the edge
1184          * between two faces. Because of this it's undefined from which face
1185          * the driver will sample. Fortunately that's not important for this
1186          * test, since all we care about is that it doesn't sample from the
1187          * other side of the surface or from the border. */
1188         color = getPixelColor(device, 320, 240);
1189         ok(color == 0x00ff0000 || color == 0x000000ff,
1190                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1191                 color, address_modes[x].name);
1192
1193         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1194         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1195     }
1196
1197     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1198     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1199
1200     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1201     IDirect3DCubeTexture9_Release(texture);
1202     IDirect3DSurface9_Release(surface);
1203 }
1204
1205 static void offscreen_test(IDirect3DDevice9 *device)
1206 {
1207     HRESULT hr;
1208     IDirect3DTexture9 *offscreenTexture = NULL;
1209     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1210     DWORD color;
1211
1212     static const float quad[][5] = {
1213         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1214         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1215         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1216         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1217     };
1218
1219     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1220     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1221
1222     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1223     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1224     if(!offscreenTexture) {
1225         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1226         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1227         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1228         if(!offscreenTexture) {
1229             skip("Cannot create an offscreen render target\n");
1230             goto out;
1231         }
1232     }
1233
1234     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1235     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1236     if(!backbuffer) {
1237         goto out;
1238     }
1239
1240     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1241     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1242     if(!offscreen) {
1243         goto out;
1244     }
1245
1246     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1247     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1248
1249     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1250     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1251     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1252     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1253     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1254     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1255     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1256     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1257     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1258     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1259
1260     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1261         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1262         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1263         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1264         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1265
1266         /* Draw without textures - Should result in a white quad */
1267         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1268         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1269
1270         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1271         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1272         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1273         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1274
1275         /* This time with the texture */
1276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1277         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1278
1279         IDirect3DDevice9_EndScene(device);
1280     }
1281
1282     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1283
1284     /* Center quad - should be white */
1285     color = getPixelColor(device, 320, 240);
1286     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1287     /* Some quad in the cleared part of the texture */
1288     color = getPixelColor(device, 170, 240);
1289     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1290     /* Part of the originally cleared back buffer */
1291     color = getPixelColor(device, 10, 10);
1292     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1293     if(0) {
1294         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1295          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1296          * the offscreen rendering mode this test would succeed or fail
1297          */
1298         color = getPixelColor(device, 10, 470);
1299         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1300     }
1301
1302 out:
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1305
1306     /* restore things */
1307     if(backbuffer) {
1308         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1309         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1310         IDirect3DSurface9_Release(backbuffer);
1311     }
1312     if(offscreenTexture) {
1313         IDirect3DTexture9_Release(offscreenTexture);
1314     }
1315     if(offscreen) {
1316         IDirect3DSurface9_Release(offscreen);
1317     }
1318 }
1319
1320 /* This test tests fog in combination with shaders.
1321  * What's tested: linear fog (vertex and table) with pixel shader
1322  *                linear table fog with non foggy vertex shader
1323  *                vertex fog with foggy vertex shader, non-linear
1324  *                fog with shader, non-linear fog with foggy shader,
1325  *                linear table fog with foggy shader
1326  */
1327 static void fog_with_shader_test(IDirect3DDevice9 *device)
1328 {
1329     HRESULT hr;
1330     DWORD color;
1331     union {
1332         float f;
1333         DWORD i;
1334     } start, end;
1335     unsigned int i, j;
1336
1337     /* basic vertex shader without fog computation ("non foggy") */
1338     static const DWORD vertex_shader_code1[] = {
1339         0xfffe0101,                                                             /* vs_1_1                       */
1340         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1341         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1342         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1343         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1344         0x0000ffff
1345     };
1346     /* basic vertex shader with reversed fog computation ("foggy") */
1347     static const DWORD vertex_shader_code2[] = {
1348         0xfffe0101,                                                             /* vs_1_1                        */
1349         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1350         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1351         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1352         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1353         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1354         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1355         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1356         0x0000ffff
1357     };
1358     /* basic pixel shader */
1359     static const DWORD pixel_shader_code[] = {
1360         0xffff0101,                                                             /* ps_1_1     */
1361         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1362         0x0000ffff
1363     };
1364
1365     static struct vertex quad[] = {
1366         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1367         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1368         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1369         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1370     };
1371
1372     static const D3DVERTEXELEMENT9 decl_elements[] = {
1373         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1374         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1375         D3DDECL_END()
1376     };
1377
1378     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1379     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1380     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1381
1382     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1383     static const struct test_data_t {
1384         int vshader;
1385         int pshader;
1386         D3DFOGMODE vfog;
1387         D3DFOGMODE tfog;
1388         unsigned int color[11];
1389     } test_data[] = {
1390         /* only pixel shader: */
1391         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1392         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1395         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1398         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1401         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1403         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1404         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1405         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1406
1407         /* vertex shader */
1408         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1409         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1410          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1411         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1412         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1415         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1417
1418         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1419         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1421         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1422         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1423         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1424
1425         /* vertex shader and pixel shader */
1426         /* The next 4 tests would read the fog coord output, but it isn't available.
1427          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1428          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1429          * These tests should be disabled if some other hardware behaves differently
1430          */
1431         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1432         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1433         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1434         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1435         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1436         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1437         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1438         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1439         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1440         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1441         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1442         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1443
1444         /* These use the Z coordinate with linear table fog */
1445         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1446         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1447         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1448         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1449         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1450         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1451         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1452         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1453         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1454         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1455         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1456         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1457
1458         /* Non-linear table fog without fog coord */
1459         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1460         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1461         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1462         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1463         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1464         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1465
1466 #if 0  /* FIXME: these fail on GeForce 8500 */
1467         /* foggy vertex shader */
1468         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1469         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1470          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1471         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1472         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1473          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1474         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1475         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1476          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1477         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1478         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1479          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1480 #endif
1481
1482         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1483          * all using the fixed fog-coord linear fog
1484          */
1485         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1486         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1487          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1488         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1489         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1490          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1491         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1492         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1493          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1494         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1495         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1496          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1497
1498         /* These use table fog. Here the shader-provided fog coordinate is
1499          * ignored and the z coordinate used instead
1500          */
1501         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1502         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1503         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1504         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1505         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1506         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1507         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1508         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1509         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1510     };
1511
1512     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1513     start.f=0.1f;
1514     end.f=0.9f;
1515
1516     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1517     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1518     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1519     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1520     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1521     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1522     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1523     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1524
1525     /* Setup initial states: No lighting, fog on, fog color */
1526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1527     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1528     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1529     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1530     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1531     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1532     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1533     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1534
1535     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1536     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1538     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1539
1540     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1541     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1542     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1543     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1544     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1545
1546     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1547     {
1548         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1549         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1550         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1551         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1552         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1553         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1554         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1555         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1556
1557         for(j=0; j < 11; j++)
1558         {
1559             /* Don't use the whole zrange to prevent rounding errors */
1560             quad[0].z = 0.001f + (float)j / 10.02f;
1561             quad[1].z = 0.001f + (float)j / 10.02f;
1562             quad[2].z = 0.001f + (float)j / 10.02f;
1563             quad[3].z = 0.001f + (float)j / 10.02f;
1564
1565             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1566             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1567
1568             hr = IDirect3DDevice9_BeginScene(device);
1569             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1570
1571             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1572             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1573
1574             hr = IDirect3DDevice9_EndScene(device);
1575             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1576
1577             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1578
1579             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1580             color = getPixelColor(device, 128, 240);
1581             ok(color_match(color, test_data[i].color[j], 13),
1582                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1583                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1584         }
1585     }
1586
1587     /* reset states */
1588     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1589     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1590     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1591     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1592     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1593     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1594     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1595     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1596
1597     IDirect3DVertexShader9_Release(vertex_shader[1]);
1598     IDirect3DVertexShader9_Release(vertex_shader[2]);
1599     IDirect3DPixelShader9_Release(pixel_shader[1]);
1600     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1601 }
1602
1603 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1604     unsigned int i, x, y;
1605     HRESULT hr;
1606     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1607     D3DLOCKED_RECT locked_rect;
1608
1609     /* Generate the textures */
1610     for(i=0; i<2; i++)
1611     {
1612         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1613                                             D3DPOOL_MANAGED, &texture[i], NULL);
1614         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1615
1616         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1617         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1618         for (y = 0; y < 128; ++y)
1619         {
1620             if(i)
1621             { /* Set up black texture with 2x2 texel white spot in the middle */
1622                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1623                 for (x = 0; x < 128; ++x)
1624                 {
1625                     if(y>62 && y<66 && x>62 && x<66)
1626                         *ptr++ = 0xffffffff;
1627                     else
1628                         *ptr++ = 0xff000000;
1629                 }
1630             }
1631             else
1632             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1633                * (if multiplied with bumpenvmat)
1634               */
1635                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1636                 for (x = 0; x < 128; ++x)
1637                 {
1638                     if(abs(x-64)>abs(y-64))
1639                     {
1640                         if(x < 64)
1641                             *ptr++ = 0xc000;
1642                         else
1643                             *ptr++ = 0x4000;
1644                     }
1645                     else
1646                     {
1647                         if(y < 64)
1648                             *ptr++ = 0x0040;
1649                         else
1650                             *ptr++ = 0x00c0;
1651                     }
1652                 }
1653             }
1654         }
1655         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1656         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1657
1658         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1659         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1660
1661         /* Disable texture filtering */
1662         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1663         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1664         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1665         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1666
1667         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1668         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1669         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1670         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1671     }
1672 }
1673
1674 /* test the behavior of the texbem instruction
1675  * with normal 2D and projective 2D textures
1676  */
1677 static void texbem_test(IDirect3DDevice9 *device)
1678 {
1679     HRESULT hr;
1680     DWORD color;
1681     int i;
1682
1683     static const DWORD pixel_shader_code[] = {
1684         0xffff0101,                         /* ps_1_1*/
1685         0x00000042, 0xb00f0000,             /* tex t0*/
1686         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1687         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1688         0x0000ffff
1689     };
1690     static const DWORD double_texbem_code[] =  {
1691         0xffff0103,                                         /* ps_1_3           */
1692         0x00000042, 0xb00f0000,                             /* tex t0           */
1693         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1694         0x00000042, 0xb00f0002,                             /* tex t2           */
1695         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1696         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1697         0x0000ffff                                          /* end              */
1698     };
1699
1700
1701     static const float quad[][7] = {
1702         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1703         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1704         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1705         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1706     };
1707     static const float quad_proj[][9] = {
1708         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1709         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1710         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1711         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1712     };
1713
1714     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1715         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1716         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1717         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1718         D3DDECL_END()
1719     },{
1720         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1721         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1722         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1723         D3DDECL_END()
1724     } };
1725
1726     /* use asymmetric matrix to test loading */
1727     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1728
1729     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1730     IDirect3DPixelShader9       *pixel_shader       = NULL;
1731     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1732     D3DLOCKED_RECT locked_rect;
1733
1734     generate_bumpmap_textures(device);
1735
1736     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1737     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1738     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1739     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1740     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1741
1742     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1743     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1744
1745     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1746     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1747
1748     for(i=0; i<2; i++)
1749     {
1750         if(i)
1751         {
1752             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1753             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1754         }
1755
1756         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1757         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1758         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1759         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1760
1761         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1762         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1763         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1764         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1765
1766         hr = IDirect3DDevice9_BeginScene(device);
1767         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1768
1769         if(!i)
1770             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1771         else
1772             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1773         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1774
1775         hr = IDirect3DDevice9_EndScene(device);
1776         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1777
1778         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1779         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1780
1781         color = getPixelColor(device, 320-32, 240);
1782         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783         color = getPixelColor(device, 320+32, 240);
1784         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1785         color = getPixelColor(device, 320, 240-32);
1786         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1787         color = getPixelColor(device, 320, 240+32);
1788         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1789
1790         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1791         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1792         IDirect3DPixelShader9_Release(pixel_shader);
1793
1794         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1795         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1796         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1797     }
1798
1799     /* clean up */
1800     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1801     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1802
1803     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1804     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1805
1806     for(i=0; i<2; i++)
1807     {
1808         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1809         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1810         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1811         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1812         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1813         IDirect3DTexture9_Release(texture);
1814     }
1815
1816     /* Test double texbem */
1817     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1818     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1819     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1820     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1821     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1822     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1823     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1824     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1825
1826     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1827     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1828     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1829     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1830
1831     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1832     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1833
1834     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1835     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1836     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1837     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1838     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1839     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1840
1841     {
1842         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1843 #define tex  0x00ff0000
1844 #define tex1 0x0000ff00
1845 #define origin 0x000000ff
1846         static const DWORD pixel_data[] = {
1847             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1848             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1850             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1851             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1852             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1853             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1854             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1855         };
1856 #undef tex1
1857 #undef tex2
1858 #undef origin
1859
1860         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1861         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1862         for(i = 0; i < 8; i++) {
1863             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1864         }
1865         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1866         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1867     }
1868
1869     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1870     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1872     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1873     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1874     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1875     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1876     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1877     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1878     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1879     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1880     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1881
1882     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1883     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1884     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1885     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1886     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1887     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1888     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1889     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1890     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1891     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1892
1893     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1894     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1895     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1896     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1897     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1898     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1899     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1900     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1901     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1902     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1903
1904     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1905     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1906     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1907     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1908     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1909     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1910     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1911     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1912     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1913     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1914     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1915     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1916     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1917     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1918     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1919     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1920
1921     hr = IDirect3DDevice9_BeginScene(device);
1922     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1923     if(SUCCEEDED(hr)) {
1924         static const float double_quad[] = {
1925             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1926              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1927             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1928              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1929         };
1930
1931         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1932         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1933         hr = IDirect3DDevice9_EndScene(device);
1934         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1935     }
1936     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1937     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1938     color = getPixelColor(device, 320, 240);
1939     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1940
1941     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1942     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1943     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1944     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1945     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1946     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1947     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1948     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1949     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1950     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1951
1952     IDirect3DPixelShader9_Release(pixel_shader);
1953     IDirect3DTexture9_Release(texture);
1954     IDirect3DTexture9_Release(texture1);
1955     IDirect3DTexture9_Release(texture2);
1956 }
1957
1958 static void z_range_test(IDirect3DDevice9 *device)
1959 {
1960     const struct vertex quad[] =
1961     {
1962         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1963         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1964         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1965         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1966     };
1967     const struct vertex quad2[] =
1968     {
1969         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1970         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1971         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1972         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1973     };
1974
1975     const struct tvertex quad3[] =
1976     {
1977         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1978         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1979         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1980         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1981     };
1982     const struct tvertex quad4[] =
1983     {
1984         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1985         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1986         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1987         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1988     };
1989     HRESULT hr;
1990     DWORD color;
1991     IDirect3DVertexShader9 *shader;
1992     IDirect3DVertexDeclaration9 *decl;
1993     D3DCAPS9 caps;
1994     const DWORD shader_code[] = {
1995         0xfffe0101,                                     /* vs_1_1           */
1996         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1997         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1998         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1999         0x0000ffff                                      /* end              */
2000     };
2001     static const D3DVERTEXELEMENT9 decl_elements[] = {
2002         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2003         D3DDECL_END()
2004     };
2005     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2006      * then call Present. Then clear the color buffer to make sure it has some defined content
2007      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2008      * by the depth value.
2009      */
2010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2012     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2016
2017     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2018     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2019     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2020     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2021     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2022     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2024     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2025     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2026     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2027
2028     hr = IDirect3DDevice9_BeginScene(device);
2029     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2030     if(hr == D3D_OK)
2031     {
2032         /* Test the untransformed vertex path */
2033         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2034         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2035         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2036         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2038         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2039
2040         /* Test the transformed vertex path */
2041         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2042         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2043
2044         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2045         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2046         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2047         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2048         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2049         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2050
2051         hr = IDirect3DDevice9_EndScene(device);
2052         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2053     }
2054
2055     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2056     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2057
2058     /* Do not test the exact corner pixels, but go pretty close to them */
2059
2060     /* Clipped because z > 1.0 */
2061     color = getPixelColor(device, 28, 238);
2062     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2063     color = getPixelColor(device, 28, 241);
2064     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2065
2066     /* Not clipped, > z buffer clear value(0.75) */
2067     color = getPixelColor(device, 31, 238);
2068     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2069     color = getPixelColor(device, 31, 241);
2070     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2071     color = getPixelColor(device, 100, 238);
2072     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2073     color = getPixelColor(device, 100, 241);
2074     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2075
2076     /* Not clipped, < z buffer clear value */
2077     color = getPixelColor(device, 104, 238);
2078     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2079     color = getPixelColor(device, 104, 241);
2080     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2081     color = getPixelColor(device, 318, 238);
2082     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2083     color = getPixelColor(device, 318, 241);
2084     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2085
2086     /* Clipped because z < 0.0 */
2087     color = getPixelColor(device, 321, 238);
2088     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2089     color = getPixelColor(device, 321, 241);
2090     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2091
2092     /* Test the shader path */
2093     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2094     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2095         skip("Vertex shaders not supported\n");
2096         goto out;
2097     }
2098     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2099     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2100     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2101     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2102
2103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2104
2105     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2106     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2107     IDirect3DDevice9_SetVertexShader(device, shader);
2108     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2109
2110     hr = IDirect3DDevice9_BeginScene(device);
2111     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2112     if(hr == D3D_OK)
2113     {
2114         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2115         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2116         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2117         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2118         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2119         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2120         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2121         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2122         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2123         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2124
2125         hr = IDirect3DDevice9_EndScene(device);
2126         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2127     }
2128
2129     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2130     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2131     IDirect3DDevice9_SetVertexShader(device, NULL);
2132     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2133
2134     IDirect3DVertexDeclaration9_Release(decl);
2135     IDirect3DVertexShader9_Release(shader);
2136
2137     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2138     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2139     /* Z < 1.0 */
2140     color = getPixelColor(device, 28, 238);
2141     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2142
2143     /* 1.0 < z < 0.75 */
2144     color = getPixelColor(device, 31, 238);
2145     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2146     color = getPixelColor(device, 100, 238);
2147     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2148
2149     /* 0.75 < z < 0.0 */
2150     color = getPixelColor(device, 104, 238);
2151     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2152     color = getPixelColor(device, 318, 238);
2153     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2154
2155     /* 0.0 < z */
2156     color = getPixelColor(device, 321, 238);
2157     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2158
2159     out:
2160     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2161     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2162     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2163     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2164     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2165     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2166 }
2167
2168 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2169 {
2170     D3DSURFACE_DESC desc;
2171     D3DLOCKED_RECT l;
2172     HRESULT hr;
2173     unsigned int x, y;
2174     DWORD *mem;
2175
2176     memset(&desc, 0, sizeof(desc));
2177     memset(&l, 0, sizeof(l));
2178     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2179     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2180     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2181     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2182     if(FAILED(hr)) return;
2183
2184     for(y = 0; y < desc.Height; y++)
2185     {
2186         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2187         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2188         {
2189             mem[x] = color;
2190         }
2191     }
2192     hr = IDirect3DSurface9_UnlockRect(surface);
2193     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2194 }
2195
2196 /* This tests a variety of possible StretchRect() situations */
2197 static void stretchrect_test(IDirect3DDevice9 *device)
2198 {
2199     HRESULT hr;
2200     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2201     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2202     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2203     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2204     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2205     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2206     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2207     IDirect3DSurface9 *orig_rt = NULL;
2208     DWORD color;
2209
2210     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2211     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2212     if(!orig_rt) {
2213         goto out;
2214     }
2215
2216     /* Create our temporary surfaces in system memory */
2217     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2219     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2220     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2221
2222     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2223     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2225     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2226     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2227     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2228     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2229
2230     /* Create render target surfaces */
2231     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2232     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2233     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2234     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2235     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2236     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2237
2238     /* Create render target textures */
2239     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2240     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2241     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2242     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2243     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2244     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2245     if (tex_rt32) {
2246         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2247         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2248     }
2249     if (tex_rt64) {
2250         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2251         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2252     }
2253     if (tex_rt_dest64) {
2254         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2255         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2256     }
2257
2258     /* Create regular textures in D3DPOOL_DEFAULT */
2259     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2260     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2261     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2262     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2263     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2264     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2265     if (tex32) {
2266         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2267         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2268     }
2269     if (tex64) {
2270         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2271         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2272     }
2273     if (tex_dest64) {
2274         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2275         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2276     }
2277
2278     /*********************************************************************
2279      * Tests for when the source parameter is an offscreen plain surface *
2280      *********************************************************************/
2281
2282     /* Fill the offscreen 64x64 surface with green */
2283     if (surf_offscreen64)
2284         fill_surface(surf_offscreen64, 0xff00ff00);
2285
2286     /* offscreenplain ==> offscreenplain, same size */
2287     if(surf_offscreen64 && surf_offscreen_dest64) {
2288         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2289         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2290
2291         if (hr == D3D_OK) {
2292             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2293             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2294         }
2295     }
2296
2297     /* offscreenplain ==> rendertarget texture, same size */
2298     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2299         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2300         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2301
2302         /* We can't lock rendertarget textures, so copy to our temp surface first */
2303         if (hr == D3D_OK) {
2304             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2305             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2306         }
2307
2308         if (hr == D3D_OK) {
2309             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2310             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2311         }
2312     }
2313
2314     /* offscreenplain ==> rendertarget surface, same size */
2315     if(surf_offscreen64 && surf_rt_dest64) {
2316         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2317         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2318
2319         if (hr == D3D_OK) {
2320             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2321             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2322         }
2323     }
2324
2325     /* offscreenplain ==> texture, same size (should fail) */
2326     if(surf_offscreen64 && surf_tex_dest64) {
2327         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2328         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2329     }
2330
2331     /* Fill the smaller offscreen surface with red */
2332     fill_surface(surf_offscreen32, 0xffff0000);
2333
2334     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2335     if(surf_offscreen32 && surf_offscreen64) {
2336         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2337         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2338     }
2339
2340     /* offscreenplain ==> rendertarget texture, scaling */
2341     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2342         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2343         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2344
2345         /* We can't lock rendertarget textures, so copy to our temp surface first */
2346         if (hr == D3D_OK) {
2347             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2348             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2349         }
2350
2351         if (hr == D3D_OK) {
2352             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2353             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2354         }
2355     }
2356
2357     /* offscreenplain ==> rendertarget surface, scaling */
2358     if(surf_offscreen32 && surf_rt_dest64) {
2359         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2360         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2361
2362         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2363         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2364     }
2365
2366     /* offscreenplain ==> texture, scaling (should fail) */
2367     if(surf_offscreen32 && surf_tex_dest64) {
2368         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2369         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2370     }
2371
2372     /************************************************************
2373      * Tests for when the source parameter is a regular texture *
2374      ************************************************************/
2375
2376     /* Fill the surface of the regular texture with blue */
2377     if (surf_tex64 && surf_temp64) {
2378         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2379         fill_surface(surf_temp64, 0xff0000ff);
2380         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2381         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2382     }
2383
2384     /* texture ==> offscreenplain, same size */
2385     if(surf_tex64 && surf_offscreen64) {
2386         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2387         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2388     }
2389
2390     /* texture ==> rendertarget texture, same size */
2391     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2392         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2393         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2394
2395         /* We can't lock rendertarget textures, so copy to our temp surface first */
2396         if (hr == D3D_OK) {
2397             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2398             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2399         }
2400
2401         if (hr == D3D_OK) {
2402             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2403             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2404         }
2405     }
2406
2407     /* texture ==> rendertarget surface, same size */
2408     if(surf_tex64 && surf_rt_dest64) {
2409         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2410         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2411
2412         if (hr == D3D_OK) {
2413             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2414             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2415         }
2416     }
2417
2418     /* texture ==> texture, same size (should fail) */
2419     if(surf_tex64 && surf_tex_dest64) {
2420         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2421         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2422     }
2423
2424     /* Fill the surface of the smaller regular texture with red */
2425     if (surf_tex32 && surf_temp32) {
2426         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2427         fill_surface(surf_temp32, 0xffff0000);
2428         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2429         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2430     }
2431
2432     /* texture ==> offscreenplain, scaling (should fail) */
2433     if(surf_tex32 && surf_offscreen64) {
2434         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2435         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2436     }
2437
2438     /* texture ==> rendertarget texture, scaling */
2439     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2440         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2441         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2442
2443         /* We can't lock rendertarget textures, so copy to our temp surface first */
2444         if (hr == D3D_OK) {
2445             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2446             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2447         }
2448
2449         if (hr == D3D_OK) {
2450             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2451             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2452         }
2453     }
2454
2455     /* texture ==> rendertarget surface, scaling */
2456     if(surf_tex32 && surf_rt_dest64) {
2457         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2458         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2459
2460         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2461         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2462     }
2463
2464     /* texture ==> texture, scaling (should fail) */
2465     if(surf_tex32 && surf_tex_dest64) {
2466         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2467         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2468     }
2469
2470     /*****************************************************************
2471      * Tests for when the source parameter is a rendertarget texture *
2472      *****************************************************************/
2473
2474     /* Fill the surface of the rendertarget texture with white */
2475     if (surf_tex_rt64 && surf_temp64) {
2476         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2477         fill_surface(surf_temp64, 0xffffffff);
2478         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2479         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2480     }
2481
2482     /* rendertarget texture ==> offscreenplain, same size */
2483     if(surf_tex_rt64 && surf_offscreen64) {
2484         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2485         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2486     }
2487
2488     /* rendertarget texture ==> rendertarget texture, same size */
2489     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2490         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2491         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2492
2493         /* We can't lock rendertarget textures, so copy to our temp surface first */
2494         if (hr == D3D_OK) {
2495             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2496             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2497         }
2498
2499         if (hr == D3D_OK) {
2500             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2501             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2502         }
2503     }
2504
2505     /* rendertarget texture ==> rendertarget surface, same size */
2506     if(surf_tex_rt64 && surf_rt_dest64) {
2507         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2508         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2509
2510         if (hr == D3D_OK) {
2511             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2512             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2513         }
2514     }
2515
2516     /* rendertarget texture ==> texture, same size (should fail) */
2517     if(surf_tex_rt64 && surf_tex_dest64) {
2518         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2519         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2520     }
2521
2522     /* Fill the surface of the smaller rendertarget texture with red */
2523     if (surf_tex_rt32 && surf_temp32) {
2524         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2525         fill_surface(surf_temp32, 0xffff0000);
2526         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2527         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2528     }
2529
2530     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2531     if(surf_tex_rt32 && surf_offscreen64) {
2532         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2533         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2534     }
2535
2536     /* rendertarget texture ==> rendertarget texture, scaling */
2537     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2538         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2540
2541         /* We can't lock rendertarget textures, so copy to our temp surface first */
2542         if (hr == D3D_OK) {
2543             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2544             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2545         }
2546
2547         if (hr == D3D_OK) {
2548             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2549             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2550         }
2551     }
2552
2553     /* rendertarget texture ==> rendertarget surface, scaling */
2554     if(surf_tex_rt32 && surf_rt_dest64) {
2555         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2556         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2557
2558         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2559         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2560     }
2561
2562     /* rendertarget texture ==> texture, scaling (should fail) */
2563     if(surf_tex_rt32 && surf_tex_dest64) {
2564         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2565         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2566     }
2567
2568     /*****************************************************************
2569      * Tests for when the source parameter is a rendertarget surface *
2570      *****************************************************************/
2571
2572     /* Fill the surface of the rendertarget surface with black */
2573     if (surf_rt64)
2574         fill_surface(surf_rt64, 0xff000000);
2575
2576     /* rendertarget texture ==> offscreenplain, same size */
2577     if(surf_rt64 && surf_offscreen64) {
2578         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2579         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2580     }
2581
2582     /* rendertarget surface ==> rendertarget texture, same size */
2583     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2584         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2585         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2586
2587         /* We can't lock rendertarget textures, so copy to our temp surface first */
2588         if (hr == D3D_OK) {
2589             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2590             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2591         }
2592
2593         if (hr == D3D_OK) {
2594             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2595             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2596         }
2597     }
2598
2599     /* rendertarget surface ==> rendertarget surface, same size */
2600     if(surf_rt64 && surf_rt_dest64) {
2601         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2602         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2603
2604         if (hr == D3D_OK) {
2605             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2606             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2607         }
2608     }
2609
2610     /* rendertarget surface ==> texture, same size (should fail) */
2611     if(surf_rt64 && surf_tex_dest64) {
2612         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2613         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2614     }
2615
2616     /* Fill the surface of the smaller rendertarget texture with red */
2617     if (surf_rt32)
2618         fill_surface(surf_rt32, 0xffff0000);
2619
2620     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2621     if(surf_rt32 && surf_offscreen64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2623         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2624     }
2625
2626     /* rendertarget surface ==> rendertarget texture, scaling */
2627     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2628         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2629         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2630
2631         /* We can't lock rendertarget textures, so copy to our temp surface first */
2632         if (hr == D3D_OK) {
2633             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2634             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2635         }
2636
2637         if (hr == D3D_OK) {
2638             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2639             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2640         }
2641     }
2642
2643     /* rendertarget surface ==> rendertarget surface, scaling */
2644     if(surf_rt32 && surf_rt_dest64) {
2645         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2646         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2647
2648         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2649         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2650     }
2651
2652     /* rendertarget surface ==> texture, scaling (should fail) */
2653     if(surf_rt32 && surf_tex_dest64) {
2654         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2655         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2656     }
2657
2658     /* TODO: Test when source and destination RECT parameters are given... */
2659     /* TODO: Test format conversions */
2660
2661
2662 out:
2663     /* Clean up */
2664     if (surf_rt32)
2665         IDirect3DSurface9_Release(surf_rt32);
2666     if (surf_rt64)
2667         IDirect3DSurface9_Release(surf_rt64);
2668     if (surf_rt_dest64)
2669         IDirect3DSurface9_Release(surf_rt_dest64);
2670     if (surf_temp32)
2671         IDirect3DSurface9_Release(surf_temp32);
2672     if (surf_temp64)
2673         IDirect3DSurface9_Release(surf_temp64);
2674     if (surf_offscreen32)
2675         IDirect3DSurface9_Release(surf_offscreen32);
2676     if (surf_offscreen64)
2677         IDirect3DSurface9_Release(surf_offscreen64);
2678     if (surf_offscreen_dest64)
2679         IDirect3DSurface9_Release(surf_offscreen_dest64);
2680
2681     if (tex_rt32) {
2682         if (surf_tex_rt32)
2683             IDirect3DSurface9_Release(surf_tex_rt32);
2684         IDirect3DTexture9_Release(tex_rt32);
2685     }
2686     if (tex_rt64) {
2687         if (surf_tex_rt64)
2688             IDirect3DSurface9_Release(surf_tex_rt64);
2689         IDirect3DTexture9_Release(tex_rt64);
2690     }
2691     if (tex_rt_dest64) {
2692         if (surf_tex_rt_dest64)
2693             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2694         IDirect3DTexture9_Release(tex_rt_dest64);
2695     }
2696     if (tex32) {
2697         if (surf_tex32)
2698             IDirect3DSurface9_Release(surf_tex32);
2699         IDirect3DTexture9_Release(tex32);
2700     }
2701     if (tex64) {
2702         if (surf_tex64)
2703             IDirect3DSurface9_Release(surf_tex64);
2704         IDirect3DTexture9_Release(tex64);
2705     }
2706     if (tex_dest64) {
2707         if (surf_tex_dest64)
2708             IDirect3DSurface9_Release(surf_tex_dest64);
2709         IDirect3DTexture9_Release(tex_dest64);
2710     }
2711
2712     if (orig_rt) {
2713         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2714         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2715         IDirect3DSurface9_Release(orig_rt);
2716     }
2717 }
2718
2719 static void maxmip_test(IDirect3DDevice9 *device)
2720 {
2721     IDirect3DTexture9 *texture = NULL;
2722     IDirect3DSurface9 *surface = NULL;
2723     HRESULT hr;
2724     DWORD color;
2725     const float quads[] = {
2726         -1.0,   -1.0,   0.0,    0.0,    0.0,
2727         -1.0,    0.0,   0.0,    0.0,    1.0,
2728          0.0,   -1.0,   0.0,    1.0,    0.0,
2729          0.0,    0.0,   0.0,    1.0,    1.0,
2730
2731          0.0,   -1.0,   0.0,    0.0,    0.0,
2732          0.0,    0.0,   0.0,    0.0,    1.0,
2733          1.0,   -1.0,   0.0,    1.0,    0.0,
2734          1.0,    0.0,   0.0,    1.0,    1.0,
2735
2736          0.0,    0.0,   0.0,    0.0,    0.0,
2737          0.0,    1.0,   0.0,    0.0,    1.0,
2738          1.0,    0.0,   0.0,    1.0,    0.0,
2739          1.0,    1.0,   0.0,    1.0,    1.0,
2740
2741         -1.0,    0.0,   0.0,    0.0,    0.0,
2742         -1.0,    1.0,   0.0,    0.0,    1.0,
2743          0.0,    0.0,   0.0,    1.0,    0.0,
2744          0.0,    1.0,   0.0,    1.0,    1.0,
2745     };
2746
2747     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2748     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2749
2750     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2751                                         &texture, NULL);
2752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2753     if(!texture)
2754     {
2755         skip("Failed to create test texture\n");
2756         return;
2757     }
2758
2759     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2760     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2761     fill_surface(surface, 0xffff0000);
2762     IDirect3DSurface9_Release(surface);
2763     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2764     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2765     fill_surface(surface, 0xff00ff00);
2766     IDirect3DSurface9_Release(surface);
2767     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2768     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2769     fill_surface(surface, 0xff0000ff);
2770     IDirect3DSurface9_Release(surface);
2771
2772     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2773     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2774     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2775     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2776
2777     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2778     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2779
2780     hr = IDirect3DDevice9_BeginScene(device);
2781     if(SUCCEEDED(hr))
2782     {
2783         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2784         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2786         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2787
2788         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2789         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2791         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2792
2793         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2794         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2796         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2797
2798         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2799         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2800         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2801         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2802         hr = IDirect3DDevice9_EndScene(device);
2803         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
2804     }
2805
2806     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2807     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2808     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2809     color = getPixelColor(device, 160, 360);
2810     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2811     color = getPixelColor(device, 160, 120);
2812     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2813     color = getPixelColor(device, 480, 120);
2814     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2815     color = getPixelColor(device, 480, 360);
2816     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2817
2818     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2819     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2820
2821     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2822     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2823
2824     hr = IDirect3DDevice9_BeginScene(device);
2825     if(SUCCEEDED(hr))
2826     {
2827         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2828         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2829         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2830         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2831
2832         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2833         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2834         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2835         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2836
2837         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2838         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2839         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2840         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2841
2842         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2843         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2845         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2846         hr = IDirect3DDevice9_EndScene(device);
2847         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
2848     }
2849
2850     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2851     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2852     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2853      * samples from the highest level in the texture(level 2)
2854      */
2855     color = getPixelColor(device, 160, 360);
2856     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2857     color = getPixelColor(device, 160, 120);
2858     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2859     color = getPixelColor(device, 480, 120);
2860     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2861     color = getPixelColor(device, 480, 360);
2862     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2863
2864     hr = IDirect3DDevice9_BeginScene(device);
2865     if(SUCCEEDED(hr))
2866     {
2867         DWORD ret;
2868
2869         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2870         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2871         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2872         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2873         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2874         ret = IDirect3DTexture9_SetLOD(texture, 1);
2875         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2876         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2877         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2878
2879         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2880         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2881         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2882         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2883         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2884         ret = IDirect3DTexture9_SetLOD(texture, 2);
2885         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2886         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2887         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2888
2889         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2890         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2891         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2892         ret = IDirect3DTexture9_SetLOD(texture, 1);
2893         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2895         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2896
2897         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2898         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2899         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2900         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2901         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2902         ret = IDirect3DTexture9_SetLOD(texture, 1);
2903         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2904         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2905         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2906         hr = IDirect3DDevice9_EndScene(device);
2907     }
2908
2909     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2910     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2911     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2912      * samples from the highest level in the texture(level 2)
2913      */
2914     color = getPixelColor(device, 160, 360);
2915     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2916     color = getPixelColor(device, 160, 120);
2917     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2918     color = getPixelColor(device, 480, 120);
2919     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2920     color = getPixelColor(device, 480, 360);
2921     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2922
2923     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2924     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2925     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2926     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2927     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2928     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2929     IDirect3DTexture9_Release(texture);
2930 }
2931
2932 static void release_buffer_test(IDirect3DDevice9 *device)
2933 {
2934     IDirect3DVertexBuffer9 *vb = NULL;
2935     IDirect3DIndexBuffer9 *ib = NULL;
2936     HRESULT hr;
2937     BYTE *data;
2938     LONG ref;
2939
2940     static const struct vertex quad[] = {
2941         {-1.0,      -1.0,       0.1,        0xffff0000},
2942         {-1.0,       1.0,       0.1,        0xffff0000},
2943         { 1.0,       1.0,       0.1,        0xffff0000},
2944
2945         {-1.0,      -1.0,       0.1,        0xff00ff00},
2946         {-1.0,       1.0,       0.1,        0xff00ff00},
2947         { 1.0,       1.0,       0.1,        0xff00ff00}
2948     };
2949     short indices[] = {3, 4, 5};
2950
2951     /* Index and vertex buffers should always be creatable */
2952     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2953                                               D3DPOOL_MANAGED, &vb, NULL);
2954     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2955     if(!vb) {
2956         skip("Failed to create a vertex buffer\n");
2957         return;
2958     }
2959     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2960     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2961     if(!ib) {
2962         skip("Failed to create an index buffer\n");
2963         return;
2964     }
2965
2966     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2967     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2968     memcpy(data, quad, sizeof(quad));
2969     hr = IDirect3DVertexBuffer9_Unlock(vb);
2970     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2971
2972     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2973     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2974     memcpy(data, indices, sizeof(indices));
2975     hr = IDirect3DIndexBuffer9_Unlock(ib);
2976     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2977
2978     hr = IDirect3DDevice9_SetIndices(device, ib);
2979     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2980     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2981     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2982     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2983     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2984
2985     /* Now destroy the bound index buffer and draw again */
2986     ref = IDirect3DIndexBuffer9_Release(ib);
2987     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2988
2989     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2990     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2991
2992     hr = IDirect3DDevice9_BeginScene(device);
2993     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2994     if(SUCCEEDED(hr))
2995     {
2996         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2997          * making assumptions about the indices or vertices
2998          */
2999         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3000         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3001         hr = IDirect3DDevice9_EndScene(device);
3002         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3003     }
3004
3005     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3006     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3007
3008     hr = IDirect3DDevice9_SetIndices(device, NULL);
3009     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3010     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3011     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3012
3013     /* Index buffer was already destroyed as part of the test */
3014     IDirect3DVertexBuffer9_Release(vb);
3015 }
3016
3017 static void float_texture_test(IDirect3DDevice9 *device)
3018 {
3019     IDirect3D9 *d3d = NULL;
3020     HRESULT hr;
3021     IDirect3DTexture9 *texture = NULL;
3022     D3DLOCKED_RECT lr;
3023     float *data;
3024     DWORD color;
3025     float quad[] = {
3026         -1.0,      -1.0,       0.1,     0.0,    0.0,
3027         -1.0,       1.0,       0.1,     0.0,    1.0,
3028          1.0,      -1.0,       0.1,     1.0,    0.0,
3029          1.0,       1.0,       0.1,     1.0,    1.0,
3030     };
3031
3032     memset(&lr, 0, sizeof(lr));
3033     IDirect3DDevice9_GetDirect3D(device, &d3d);
3034     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3035                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3036         skip("D3DFMT_R32F textures not supported\n");
3037         goto out;
3038     }
3039
3040     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3041                                         D3DPOOL_MANAGED, &texture, NULL);
3042     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3043     if(!texture) {
3044         skip("Failed to create R32F texture\n");
3045         goto out;
3046     }
3047
3048     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3049     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3050     data = lr.pBits;
3051     *data = 0.0;
3052     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3053     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3054
3055     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3056     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3057
3058     hr = IDirect3DDevice9_BeginScene(device);
3059     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3060     if(SUCCEEDED(hr))
3061     {
3062         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3063         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3064
3065         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3066         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3067
3068         hr = IDirect3DDevice9_EndScene(device);
3069         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3070     }
3071     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3072     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3073
3074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3075     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3076
3077     color = getPixelColor(device, 240, 320);
3078     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3079
3080 out:
3081     if(texture) IDirect3DTexture9_Release(texture);
3082     IDirect3D9_Release(d3d);
3083 }
3084
3085 static void g16r16_texture_test(IDirect3DDevice9 *device)
3086 {
3087     IDirect3D9 *d3d = NULL;
3088     HRESULT hr;
3089     IDirect3DTexture9 *texture = NULL;
3090     D3DLOCKED_RECT lr;
3091     DWORD *data;
3092     DWORD color;
3093     float quad[] = {
3094        -1.0,      -1.0,       0.1,     0.0,    0.0,
3095        -1.0,       1.0,       0.1,     0.0,    1.0,
3096         1.0,      -1.0,       0.1,     1.0,    0.0,
3097         1.0,       1.0,       0.1,     1.0,    1.0,
3098     };
3099
3100     memset(&lr, 0, sizeof(lr));
3101     IDirect3DDevice9_GetDirect3D(device, &d3d);
3102     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3103        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3104            skip("D3DFMT_G16R16 textures not supported\n");
3105            goto out;
3106     }
3107
3108     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3109                                         D3DPOOL_MANAGED, &texture, NULL);
3110     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3111     if(!texture) {
3112         skip("Failed to create D3DFMT_G16R16 texture\n");
3113         goto out;
3114     }
3115
3116     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3117     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3118     data = lr.pBits;
3119     *data = 0x0f00f000;
3120     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3121     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3122
3123     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3124     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3125
3126     hr = IDirect3DDevice9_BeginScene(device);
3127     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3128     if(SUCCEEDED(hr))
3129     {
3130         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3131         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3132
3133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3134         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3135
3136         hr = IDirect3DDevice9_EndScene(device);
3137         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3138     }
3139     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3140     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3141
3142     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3143     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3144
3145     color = getPixelColor(device, 240, 320);
3146     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3147        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3148
3149 out:
3150     if(texture) IDirect3DTexture9_Release(texture);
3151     IDirect3D9_Release(d3d);
3152 }
3153
3154 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3155 {
3156     HRESULT hr;
3157     IDirect3D9 *d3d;
3158     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3159     D3DCAPS9 caps;
3160     IDirect3DTexture9 *texture = NULL;
3161     IDirect3DVolumeTexture9 *volume = NULL;
3162     unsigned int x, y, z;
3163     D3DLOCKED_RECT lr;
3164     D3DLOCKED_BOX lb;
3165     DWORD color;
3166     UINT w, h;
3167     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3168     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3169                            0.0, 1.0, 0.0, 0.0,
3170                            0.0, 0.0, 1.0, 0.0,
3171                            0.0, 0.0, 0.0, 1.0};
3172     static const D3DVERTEXELEMENT9 decl_elements[] = {
3173         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3174         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3175         D3DDECL_END()
3176     };
3177     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3178         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3179         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3180         D3DDECL_END()
3181     };
3182     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3183         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3184         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3185         D3DDECL_END()
3186     };
3187     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3188                                                  0x00, 0xff, 0x00, 0x00,
3189                                                  0x00, 0x00, 0x00, 0x00,
3190                                                  0x00, 0x00, 0x00, 0x00};
3191
3192     memset(&lr, 0, sizeof(lr));
3193     memset(&lb, 0, sizeof(lb));
3194     IDirect3DDevice9_GetDirect3D(device, &d3d);
3195     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3196                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3197         fmt = D3DFMT_A16B16G16R16;
3198     }
3199     IDirect3D9_Release(d3d);
3200
3201     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3203     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3205     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3207     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3208     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3209     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3210     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3211     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3212     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3213     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3214     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3215     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3216     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3217     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3218     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3219     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3220     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3221     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3222     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3223     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3224     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3225
3226     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3227     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3228     w = min(1024, caps.MaxTextureWidth);
3229     h = min(1024, caps.MaxTextureHeight);
3230     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3231                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3232     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3233     if(!texture) {
3234         skip("Failed to create the test texture\n");
3235         return;
3236     }
3237
3238     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3239      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3240      * 1.0 in red and green for the x and y coords
3241      */
3242     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3243     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3244     for(y = 0; y < h; y++) {
3245         for(x = 0; x < w; x++) {
3246             double r_f = (double) y / (double) h;
3247             double g_f = (double) x / (double) w;
3248             if(fmt == D3DFMT_A16B16G16R16) {
3249                 unsigned short r, g;
3250                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3251                 r = (unsigned short) (r_f * 65536.0);
3252                 g = (unsigned short) (g_f * 65536.0);
3253                 dst[0] = r;
3254                 dst[1] = g;
3255                 dst[2] = 0;
3256                 dst[3] = 65535;
3257             } else {
3258                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3259                 unsigned char r = (unsigned char) (r_f * 255.0);
3260                 unsigned char g = (unsigned char) (g_f * 255.0);
3261                 dst[0] = 0;
3262                 dst[1] = g;
3263                 dst[2] = r;
3264                 dst[3] = 255;
3265             }
3266         }
3267     }
3268     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3269     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3270     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3272
3273     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3274     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3275     hr = IDirect3DDevice9_BeginScene(device);
3276     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3277     if(SUCCEEDED(hr))
3278     {
3279         float quad1[] = {
3280             -1.0,      -1.0,       0.1,     1.0,    1.0,
3281             -1.0,       0.0,       0.1,     1.0,    1.0,
3282              0.0,      -1.0,       0.1,     1.0,    1.0,
3283              0.0,       0.0,       0.1,     1.0,    1.0,
3284         };
3285         float quad2[] = {
3286             -1.0,       0.0,       0.1,     1.0,    1.0,
3287             -1.0,       1.0,       0.1,     1.0,    1.0,
3288              0.0,       0.0,       0.1,     1.0,    1.0,
3289              0.0,       1.0,       0.1,     1.0,    1.0,
3290         };
3291         float quad3[] = {
3292              0.0,       0.0,       0.1,     0.5,    0.5,
3293              0.0,       1.0,       0.1,     0.5,    0.5,
3294              1.0,       0.0,       0.1,     0.5,    0.5,
3295              1.0,       1.0,       0.1,     0.5,    0.5,
3296         };
3297         float quad4[] = {
3298              320,       480,       0.1,     1.0,    0.0,    1.0,
3299              320,       240,       0.1,     1.0,    0.0,    1.0,
3300              640,       480,       0.1,     1.0,    0.0,    1.0,
3301              640,       240,       0.1,     1.0,    0.0,    1.0,
3302         };
3303         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3304                           0.0, 0.0, 0.0, 0.0,
3305                           0.0, 0.0, 0.0, 0.0,
3306                           0.0, 0.0, 0.0, 0.0};
3307
3308         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3309         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3310         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3311         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3312         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3313
3314         /* What happens with transforms enabled? */
3315         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3316         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3317         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3318         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3319
3320         /* What happens if 4 coords are used, but only 2 given ?*/
3321         mat[8] = 1.0;
3322         mat[13] = 1.0;
3323         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3324         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3325         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3326         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3327         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3328         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3329
3330         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3331          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3332          * due to the coords in the vertices. (turns out red, indeed)
3333          */
3334         memset(mat, 0, sizeof(mat));
3335         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3336         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3337         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3338         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3339         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3340         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3341         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3342         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3343
3344         hr = IDirect3DDevice9_EndScene(device);
3345         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3346     }
3347     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3348     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3349     color = getPixelColor(device, 160, 360);
3350     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3351     color = getPixelColor(device, 160, 120);
3352     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3353     color = getPixelColor(device, 480, 120);
3354     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3355     color = getPixelColor(device, 480, 360);
3356     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3357
3358     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3359     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3360
3361     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3362     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3363     hr = IDirect3DDevice9_BeginScene(device);
3364     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3365     if(SUCCEEDED(hr))
3366     {
3367         float quad1[] = {
3368             -1.0,      -1.0,       0.1,     0.8,    0.2,
3369             -1.0,       0.0,       0.1,     0.8,    0.2,
3370              0.0,      -1.0,       0.1,     0.8,    0.2,
3371              0.0,       0.0,       0.1,     0.8,    0.2,
3372         };
3373         float quad2[] = {
3374             -1.0,       0.0,       0.1,     0.5,    1.0,
3375             -1.0,       1.0,       0.1,     0.5,    1.0,
3376              0.0,       0.0,       0.1,     0.5,    1.0,
3377              0.0,       1.0,       0.1,     0.5,    1.0,
3378         };
3379         float quad3[] = {
3380              0.0,       0.0,       0.1,     0.5,    1.0,
3381              0.0,       1.0,       0.1,     0.5,    1.0,
3382              1.0,       0.0,       0.1,     0.5,    1.0,
3383              1.0,       1.0,       0.1,     0.5,    1.0,
3384         };
3385         float quad4[] = {
3386              0.0,      -1.0,       0.1,     0.8,    0.2,
3387              0.0,       0.0,       0.1,     0.8,    0.2,
3388              1.0,      -1.0,       0.1,     0.8,    0.2,
3389              1.0,       0.0,       0.1,     0.8,    0.2,
3390         };
3391         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3392                           0.0, 0.0, 0.0, 0.0,
3393                           0.0, 1.0, 0.0, 0.0,
3394                           0.0, 0.0, 0.0, 0.0};
3395
3396         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3397          */
3398         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3399         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3400         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3401         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3402
3403         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3404         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3405
3406         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3407          * it behaves like COUNT2 because normal textures require 2 coords
3408          */
3409         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3410         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3412         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3413
3414         /* Just to be sure, the same as quad2 above */
3415         memset(mat, 0, sizeof(mat));
3416         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3417         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3418         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3419         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3420         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3421         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3422
3423         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3424          * used? And what happens to the first?
3425          */
3426         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3427         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3428         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3429         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3430
3431         hr = IDirect3DDevice9_EndScene(device);
3432         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3433     }
3434     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3435     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3436     color = getPixelColor(device, 160, 360);
3437     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3438     color = getPixelColor(device, 160, 120);
3439     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3440     color = getPixelColor(device, 480, 120);
3441     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3442        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3443     color = getPixelColor(device, 480, 360);
3444     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3445        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3446
3447     IDirect3DTexture9_Release(texture);
3448
3449     /* Test projected textures, without any fancy matrices */
3450     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3451     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3452     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3453     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3454     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3455     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3456     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3457     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3458
3459     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3460     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3461     for(x = 0; x < 4; x++) {
3462         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3463     }
3464     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3465     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3466     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3467     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3468
3469     hr = IDirect3DDevice9_BeginScene(device);
3470     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3471     if(SUCCEEDED(hr))
3472     {
3473         const float proj_quads[] = {
3474            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3475             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3476            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3477             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3478            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3479             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3480            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3481             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3482         };
3483
3484         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3485         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3486         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3487         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3488
3489         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3490         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3491         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3492         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3493
3494         hr = IDirect3DDevice9_EndScene(device);
3495         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3496     }
3497
3498     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3499     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3500     IDirect3DTexture9_Release(texture);
3501
3502     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3503     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3504     color = getPixelColor(device, 158, 118);
3505     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3506     color = getPixelColor(device, 162, 118);
3507     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3508     color = getPixelColor(device, 158, 122);
3509     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3510     color = getPixelColor(device, 162, 122);
3511     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3512
3513     color = getPixelColor(device, 158, 178);
3514     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3515     color = getPixelColor(device, 162, 178);
3516     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3517     color = getPixelColor(device, 158, 182);
3518     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3519     color = getPixelColor(device, 162, 182);
3520     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3521
3522     color = getPixelColor(device, 318, 118);
3523     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3524     color = getPixelColor(device, 322, 118);
3525     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3526     color = getPixelColor(device, 318, 122);
3527     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3528     color = getPixelColor(device, 322, 122);
3529     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3530
3531     color = getPixelColor(device, 318, 178);
3532     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3533     color = getPixelColor(device, 322, 178);
3534     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3535     color = getPixelColor(device, 318, 182);
3536     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3537     color = getPixelColor(device, 322, 182);
3538     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3539
3540     color = getPixelColor(device, 238, 298);
3541     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3542     color = getPixelColor(device, 242, 298);
3543     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3544     color = getPixelColor(device, 238, 302);
3545     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3546     color = getPixelColor(device, 242, 302);
3547     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3548
3549     color = getPixelColor(device, 238, 388);
3550     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3551     color = getPixelColor(device, 242, 388);
3552     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3553     color = getPixelColor(device, 238, 392);
3554     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3555     color = getPixelColor(device, 242, 392);
3556     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3557
3558     color = getPixelColor(device, 478, 298);
3559     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3560     color = getPixelColor(device, 482, 298);
3561     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3562     color = getPixelColor(device, 478, 302);
3563     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3564     color = getPixelColor(device, 482, 302);
3565     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3566
3567     color = getPixelColor(device, 478, 388);
3568     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3569     color = getPixelColor(device, 482, 388);
3570     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3571     color = getPixelColor(device, 478, 392);
3572     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3573     color = getPixelColor(device, 482, 392);
3574     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3575
3576     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3577     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3578     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3579      * Thus watch out if sampling from texels between 0 and 1.
3580      */
3581     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3582     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3583        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3584     if(!volume) {
3585         skip("Failed to create a volume texture\n");
3586         goto out;
3587     }
3588
3589     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3590     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3591     for(z = 0; z < 32; z++) {
3592         for(y = 0; y < 32; y++) {
3593             for(x = 0; x < 32; x++) {
3594                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3595                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3596                 float r_f = (float) x / 31.0;
3597                 float g_f = (float) y / 31.0;
3598                 float b_f = (float) z / 31.0;
3599
3600                 if(fmt == D3DFMT_A16B16G16R16) {
3601                     unsigned short *mem_s = mem;
3602                     mem_s[0]  = r_f * 65535.0;
3603                     mem_s[1]  = g_f * 65535.0;
3604                     mem_s[2]  = b_f * 65535.0;
3605                     mem_s[3]  = 65535;
3606                 } else {
3607                     unsigned char *mem_c = mem;
3608                     mem_c[0]  = b_f * 255.0;
3609                     mem_c[1]  = g_f * 255.0;
3610                     mem_c[2]  = r_f * 255.0;
3611                     mem_c[3]  = 255;
3612                 }
3613             }
3614         }
3615     }
3616     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3617     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3618
3619     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3620     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3621
3622     hr = IDirect3DDevice9_BeginScene(device);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3624     if(SUCCEEDED(hr))
3625     {
3626         float quad1[] = {
3627             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3628             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3629              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3630              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3631         };
3632         float quad2[] = {
3633             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3634             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3635              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3636              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3637         };
3638         float quad3[] = {
3639              0.0,       0.0,       0.1,     0.0,    0.0,
3640              0.0,       1.0,       0.1,     0.0,    0.0,
3641              1.0,       0.0,       0.1,     0.0,    0.0,
3642              1.0,       1.0,       0.1,     0.0,    0.0
3643         };
3644         float quad4[] = {
3645              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3646              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3647              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3648              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3649         };
3650         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3651                          0.0, 0.0, 1.0, 0.0,
3652                          0.0, 1.0, 0.0, 0.0,
3653                          0.0, 0.0, 0.0, 1.0};
3654         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3655         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3656
3657         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3658          * values
3659          */
3660         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3661         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3662         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3663         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3665         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3666
3667         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3668          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3669          * otherwise the w will be missing(blue).
3670          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3671          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3672          */
3673         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3674         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3675         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3676         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3677
3678         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3679         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3680         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3682         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3683         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3684         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3685         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3686         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3687
3688         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3689          * disable. ATI extends it up to the amount of values needed for the volume texture
3690          */
3691         memset(mat, 0, sizeof(mat));
3692         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3694         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3695         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3696         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3697         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3698         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3699         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3700
3701         hr = IDirect3DDevice9_EndScene(device);
3702         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3703     }
3704     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3705     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3706
3707     color = getPixelColor(device, 160, 360);
3708     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3709     color = getPixelColor(device, 160, 120);
3710     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3711        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3712     color = getPixelColor(device, 480, 120);
3713     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3714     color = getPixelColor(device, 480, 360);
3715     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3716
3717     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3719     hr = IDirect3DDevice9_BeginScene(device);
3720     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3721     if(SUCCEEDED(hr))
3722     {
3723         float quad1[] = {
3724             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3725             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3726              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3727              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3728         };
3729         float quad2[] = {
3730             -1.0,       0.0,       0.1,
3731             -1.0,       1.0,       0.1,
3732              0.0,       0.0,       0.1,
3733              0.0,       1.0,       0.1,
3734         };
3735         float quad3[] = {
3736              0.0,       0.0,       0.1,     1.0,
3737              0.0,       1.0,       0.1,     1.0,
3738              1.0,       0.0,       0.1,     1.0,
3739              1.0,       1.0,       0.1,     1.0
3740         };
3741         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3742                            0.0, 0.0, 0.0, 0.0,
3743                            0.0, 0.0, 0.0, 0.0,
3744                            0.0, 1.0, 0.0, 0.0};
3745         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3746                            1.0, 0.0, 0.0, 0.0,
3747                            0.0, 1.0, 0.0, 0.0,
3748                            0.0, 0.0, 1.0, 0.0};
3749         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3750         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3751
3752         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3753          */
3754         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3755         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3756         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3757         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3758         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3759         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3760
3761         /* None passed */
3762         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3763         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3764         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3765         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3767         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3768
3769         /* 4 used, 1 passed */
3770         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3771         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3772         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3773         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3775         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3776
3777         hr = IDirect3DDevice9_EndScene(device);
3778         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3779     }
3780     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3781     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3782     color = getPixelColor(device, 160, 360);
3783     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3784     color = getPixelColor(device, 160, 120);
3785     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3786     color = getPixelColor(device, 480, 120);
3787     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3788     /* Quad4: unused */
3789
3790     IDirect3DVolumeTexture9_Release(volume);
3791
3792     out:
3793     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3794     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3795     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3796     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3797     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3798     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3799     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3801     IDirect3DVertexDeclaration9_Release(decl);
3802     IDirect3DVertexDeclaration9_Release(decl2);
3803     IDirect3DVertexDeclaration9_Release(decl3);
3804 }
3805
3806 static void texdepth_test(IDirect3DDevice9 *device)
3807 {
3808     IDirect3DPixelShader9 *shader;
3809     HRESULT hr;
3810     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3811     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3812     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3813     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3814     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3815     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3816     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3817     DWORD shader_code[] = {
3818         0xffff0104,                                                                 /* ps_1_4               */
3819         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3820         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3821         0x0000fffd,                                                                 /* phase                */
3822         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3823         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3824         0x0000ffff                                                                  /* end                  */
3825     };
3826     DWORD color;
3827     float vertex[] = {
3828        -1.0,   -1.0,    0.0,
3829         1.0,   -1.0,    1.0,
3830        -1.0,    1.0,    0.0,
3831         1.0,    1.0,    1.0
3832     };
3833
3834     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3835     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3836
3837     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3838     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3839     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3840     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3842     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3844     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3845     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3846     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
3847
3848     /* Fill the depth buffer with a gradient */
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         hr = IDirect3DDevice9_EndScene(device);
3856         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3857     }
3858
3859     /* Now perform the actual tests. Same geometry, but with the shader */
3860     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3861     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3863     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3864     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3865     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3866
3867     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3868     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3869     hr = IDirect3DDevice9_BeginScene(device);
3870     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3871     if(SUCCEEDED(hr))
3872     {
3873         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3874         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3875
3876         hr = IDirect3DDevice9_EndScene(device);
3877         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3878     }
3879
3880     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3881     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3882     color = getPixelColor(device, 158, 240);
3883     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3884     color = getPixelColor(device, 162, 240);
3885     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3886
3887     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3888     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3889
3890     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3891     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3892     hr = IDirect3DDevice9_BeginScene(device);
3893     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3894     if(SUCCEEDED(hr))
3895     {
3896         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3897         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3898
3899         hr = IDirect3DDevice9_EndScene(device);
3900         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3901     }
3902
3903     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3905     color = getPixelColor(device, 318, 240);
3906     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3907     color = getPixelColor(device, 322, 240);
3908     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3909
3910     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3911     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3912
3913     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3914     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3915     hr = IDirect3DDevice9_BeginScene(device);
3916     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3917     if(SUCCEEDED(hr))
3918     {
3919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3920         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3921
3922         hr = IDirect3DDevice9_EndScene(device);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3924     }
3925     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3926     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3927
3928     color = getPixelColor(device, 1, 240);
3929     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3930
3931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3932     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3933
3934     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3935     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3936     hr = IDirect3DDevice9_BeginScene(device);
3937     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3938     if(SUCCEEDED(hr))
3939     {
3940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3941         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3942
3943         hr = IDirect3DDevice9_EndScene(device);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3945     }
3946     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3947     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3948     color = getPixelColor(device, 318, 240);
3949     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3950     color = getPixelColor(device, 322, 240);
3951     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3952
3953     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3954     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3955
3956     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3957     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3958     hr = IDirect3DDevice9_BeginScene(device);
3959     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3960     if(SUCCEEDED(hr))
3961     {
3962         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3963         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3964
3965         hr = IDirect3DDevice9_EndScene(device);
3966         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3967     }
3968     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3969     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3970
3971     color = getPixelColor(device, 1, 240);
3972     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3973
3974     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3975     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3976
3977     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3978     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3979     hr = IDirect3DDevice9_BeginScene(device);
3980     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3981     if(SUCCEEDED(hr))
3982     {
3983         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3984         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3985
3986         hr = IDirect3DDevice9_EndScene(device);
3987         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3988     }
3989     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3990     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3991
3992     color = getPixelColor(device, 638, 240);
3993     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3994
3995     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3996     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3997
3998     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3999     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4000     hr = IDirect3DDevice9_BeginScene(device);
4001     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4002     if(SUCCEEDED(hr))
4003     {
4004         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4005         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4006
4007         hr = IDirect3DDevice9_EndScene(device);
4008         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4009     }
4010     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4011     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4012
4013     color = getPixelColor(device, 638, 240);
4014     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4015
4016     /* Cleanup */
4017     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4018     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4019     IDirect3DPixelShader9_Release(shader);
4020
4021     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4022     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4024     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4025 }
4026
4027 static void texkill_test(IDirect3DDevice9 *device)
4028 {
4029     IDirect3DPixelShader9 *shader;
4030     HRESULT hr;
4031     DWORD color;
4032
4033     const float vertex[] = {
4034     /*                          bottom  top    right    left */
4035         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4036          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4037         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4038          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4039     };
4040
4041     DWORD shader_code_11[] = {
4042     0xffff0101,                                                             /* ps_1_1                     */
4043     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4044     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4045     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4046     0x0000ffff                                                              /* end                        */
4047     };
4048     DWORD shader_code_20[] = {
4049     0xffff0200,                                                             /* ps_2_0                     */
4050     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4051     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4052     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4053     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4054     0x0000ffff                                                              /* end                        */
4055     };
4056
4057     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4058     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4059     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4060     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4061
4062     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4063     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4064     hr = IDirect3DDevice9_BeginScene(device);
4065     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4066     if(SUCCEEDED(hr))
4067     {
4068         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4069         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4070         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4071         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4072         hr = IDirect3DDevice9_EndScene(device);
4073         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4074     }
4075     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4077     color = getPixelColor(device, 63, 46);
4078     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4079     color = getPixelColor(device, 66, 46);
4080     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4081     color = getPixelColor(device, 63, 49);
4082     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4083     color = getPixelColor(device, 66, 49);
4084     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4085
4086     color = getPixelColor(device, 578, 46);
4087     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4088     color = getPixelColor(device, 575, 46);
4089     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4090     color = getPixelColor(device, 578, 49);
4091     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4092     color = getPixelColor(device, 575, 49);
4093     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4094
4095     color = getPixelColor(device, 63, 430);
4096     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4097     color = getPixelColor(device, 63, 433);
4098     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4099     color = getPixelColor(device, 66, 433);
4100     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4101     color = getPixelColor(device, 66, 430);
4102     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4103
4104     color = getPixelColor(device, 578, 430);
4105     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4106     color = getPixelColor(device, 578, 433);
4107     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4108     color = getPixelColor(device, 575, 433);
4109     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4110     color = getPixelColor(device, 575, 430);
4111     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4112
4113     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4114     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4115     IDirect3DPixelShader9_Release(shader);
4116
4117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4118     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4119     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4120     if(FAILED(hr)) {
4121         skip("Failed to create 2.0 test shader, most likely not supported\n");
4122         return;
4123     }
4124
4125     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4126     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4127     hr = IDirect3DDevice9_BeginScene(device);
4128     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4129     if(SUCCEEDED(hr))
4130     {
4131         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4132         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4133         hr = IDirect3DDevice9_EndScene(device);
4134         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4135     }
4136     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4137
4138     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4139     color = getPixelColor(device, 63, 46);
4140     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4141     color = getPixelColor(device, 66, 46);
4142     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4143     color = getPixelColor(device, 63, 49);
4144     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4145     color = getPixelColor(device, 66, 49);
4146     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4147
4148     color = getPixelColor(device, 578, 46);
4149     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4150     color = getPixelColor(device, 575, 46);
4151     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4152     color = getPixelColor(device, 578, 49);
4153     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4154     color = getPixelColor(device, 575, 49);
4155     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4156
4157     color = getPixelColor(device, 63, 430);
4158     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4159     color = getPixelColor(device, 63, 433);
4160     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4161     color = getPixelColor(device, 66, 433);
4162     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4163     color = getPixelColor(device, 66, 430);
4164     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4165
4166     color = getPixelColor(device, 578, 430);
4167     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4168     color = getPixelColor(device, 578, 433);
4169     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4170     color = getPixelColor(device, 575, 433);
4171     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4172     color = getPixelColor(device, 575, 430);
4173     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4174
4175     /* Cleanup */
4176     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4177     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4178     IDirect3DPixelShader9_Release(shader);
4179 }
4180
4181 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4182 {
4183     IDirect3D9 *d3d9;
4184     HRESULT hr;
4185     IDirect3DTexture9 *texture;
4186     IDirect3DPixelShader9 *shader;
4187     IDirect3DPixelShader9 *shader2;
4188     D3DLOCKED_RECT lr;
4189     DWORD color;
4190     DWORD shader_code[] = {
4191         0xffff0101,                             /* ps_1_1       */
4192         0x00000042, 0xb00f0000,                 /* tex t0       */
4193         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4194         0x0000ffff                              /* end          */
4195     };
4196     DWORD shader_code2[] = {
4197         0xffff0101,                             /* ps_1_1       */
4198         0x00000042, 0xb00f0000,                 /* tex t0       */
4199         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4200         0x0000ffff                              /* end          */
4201     };
4202
4203     float quad[] = {
4204        -1.0,   -1.0,   0.1,     0.5,    0.5,
4205         1.0,   -1.0,   0.1,     0.5,    0.5,
4206        -1.0,    1.0,   0.1,     0.5,    0.5,
4207         1.0,    1.0,   0.1,     0.5,    0.5,
4208     };
4209
4210     memset(&lr, 0, sizeof(lr));
4211     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4212     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4213                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4214     IDirect3D9_Release(d3d9);
4215     if(FAILED(hr)) {
4216         skip("No D3DFMT_X8L8V8U8 support\n");
4217     };
4218
4219     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4220     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4221
4222     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4223     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4224     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4225     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4226     *((DWORD *) lr.pBits) = 0x11ca3141;
4227     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4228     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4229
4230     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4231     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4232     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4233     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4234
4235     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4236     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4237     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4238     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4239     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4240     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4241
4242     hr = IDirect3DDevice9_BeginScene(device);
4243     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4244     if(SUCCEEDED(hr))
4245     {
4246         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4247         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4248
4249         hr = IDirect3DDevice9_EndScene(device);
4250         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4251     }
4252     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4253     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4254     color = getPixelColor(device, 578, 430);
4255     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4256        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4257
4258     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4260     hr = IDirect3DDevice9_BeginScene(device);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4262     if(SUCCEEDED(hr))
4263     {
4264         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4265         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4266
4267         hr = IDirect3DDevice9_EndScene(device);
4268         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4269     }
4270     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4272     color = getPixelColor(device, 578, 430);
4273     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4274
4275     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4276     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4277     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4278     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4279     IDirect3DPixelShader9_Release(shader);
4280     IDirect3DPixelShader9_Release(shader2);
4281     IDirect3DTexture9_Release(texture);
4282 }
4283
4284 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4285 {
4286     HRESULT hr;
4287     IDirect3D9 *d3d;
4288     IDirect3DTexture9 *texture = NULL;
4289     IDirect3DSurface9 *surface;
4290     DWORD color;
4291     const RECT r1 = {256, 256, 512, 512};
4292     const RECT r2 = {512, 256, 768, 512};
4293     const RECT r3 = {256, 512, 512, 768};
4294     const RECT r4 = {512, 512, 768, 768};
4295     unsigned int x, y;
4296     D3DLOCKED_RECT lr;
4297     memset(&lr, 0, sizeof(lr));
4298
4299     IDirect3DDevice9_GetDirect3D(device, &d3d);
4300     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4301        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4302         skip("No autogenmipmap support\n");
4303         IDirect3D9_Release(d3d);
4304         return;
4305     }
4306     IDirect3D9_Release(d3d);
4307
4308     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4309     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4310
4311     /* Make the mipmap big, so that a smaller mipmap is used
4312      */
4313     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4314                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4315     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4316
4317     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4318     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4319     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4320     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4321     for(y = 0; y < 1024; y++) {
4322         for(x = 0; x < 1024; x++) {
4323             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4324             POINT pt;
4325
4326             pt.x = x;
4327             pt.y = y;
4328             if(PtInRect(&r1, pt)) {
4329                 *dst = 0xffff0000;
4330             } else if(PtInRect(&r2, pt)) {
4331                 *dst = 0xff00ff00;
4332             } else if(PtInRect(&r3, pt)) {
4333                 *dst = 0xff0000ff;
4334             } else if(PtInRect(&r4, pt)) {
4335                 *dst = 0xff000000;
4336             } else {
4337                 *dst = 0xffffffff;
4338             }
4339         }
4340     }
4341     hr = IDirect3DSurface9_UnlockRect(surface);
4342     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4343     IDirect3DSurface9_Release(surface);
4344
4345     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4346     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4347     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4348     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4349
4350     hr = IDirect3DDevice9_BeginScene(device);
4351     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4352     if(SUCCEEDED(hr)) {
4353         const float quad[] =  {
4354            -0.5,   -0.5,    0.1,    0.0,    0.0,
4355            -0.5,    0.5,    0.1,    0.0,    1.0,
4356             0.5,   -0.5,    0.1,    1.0,    0.0,
4357             0.5,    0.5,    0.1,    1.0,    1.0
4358         };
4359
4360         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4361         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4362         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4363         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4364         hr = IDirect3DDevice9_EndScene(device);
4365         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4366     }
4367     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4368     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4369     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4370     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4371     IDirect3DTexture9_Release(texture);
4372
4373     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4374     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4375     color = getPixelColor(device, 200, 200);
4376     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4377     color = getPixelColor(device, 280, 200);
4378     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4379     color = getPixelColor(device, 360, 200);
4380     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4381     color = getPixelColor(device, 440, 200);
4382     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4383     color = getPixelColor(device, 200, 270);
4384     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4385     color = getPixelColor(device, 280, 270);
4386     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4387     color = getPixelColor(device, 360, 270);
4388     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4389     color = getPixelColor(device, 440, 270);
4390     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4391 }
4392
4393 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4394 {
4395     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4396     IDirect3DVertexDeclaration9 *decl;
4397     HRESULT hr;
4398     DWORD color;
4399     DWORD shader_code_11[] =  {
4400         0xfffe0101,                                         /* vs_1_1           */
4401         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4402         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4403         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4404         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4405         0x0000ffff                                          /* end              */
4406     };
4407     DWORD shader_code_11_2[] =  {
4408         0xfffe0101,                                         /* vs_1_1           */
4409         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4410         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4411         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4412         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4413         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4414         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4415         0x0000ffff                                          /* end              */
4416     };
4417     DWORD shader_code_20[] =  {
4418         0xfffe0200,                                         /* vs_2_0           */
4419         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4420         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4421         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4422         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4423         0x0000ffff                                          /* end              */
4424     };
4425     DWORD shader_code_20_2[] =  {
4426         0xfffe0200,                                         /* vs_2_0           */
4427         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4428         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4429         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4430         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4431         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4432         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4433         0x0000ffff                                          /* end              */
4434     };
4435     static const D3DVERTEXELEMENT9 decl_elements[] = {
4436         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4437         D3DDECL_END()
4438     };
4439     float quad1[] = {
4440         -1.0,   -1.0,   0.1,
4441          0.0,   -1.0,   0.1,
4442         -1.0,    0.0,   0.1,
4443          0.0,    0.0,   0.1
4444     };
4445     float quad2[] = {
4446          0.0,   -1.0,   0.1,
4447          1.0,   -1.0,   0.1,
4448          0.0,    0.0,   0.1,
4449          1.0,    0.0,   0.1
4450     };
4451     float quad3[] = {
4452          0.0,    0.0,   0.1,
4453          1.0,    0.0,   0.1,
4454          0.0,    1.0,   0.1,
4455          1.0,    1.0,   0.1
4456     };
4457     float quad4[] = {
4458         -1.0,    0.0,   0.1,
4459          0.0,    0.0,   0.1,
4460         -1.0,    1.0,   0.1,
4461          0.0,    1.0,   0.1
4462     };
4463     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4464     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4465
4466     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4467     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4468
4469     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4470     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4471     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4472     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4473     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4474     if(FAILED(hr)) shader_20 = NULL;
4475     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4476     if(FAILED(hr)) shader_20_2 = NULL;
4477     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4478     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4479
4480     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4481     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4482     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4483     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4484     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4485     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4486
4487     hr = IDirect3DDevice9_BeginScene(device);
4488     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4489     if(SUCCEEDED(hr))
4490     {
4491         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4492         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4493         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4494         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4495
4496         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4497         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4498         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4499         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4500
4501         if(shader_20) {
4502             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4503             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4504             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4505             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4506         }
4507
4508         if(shader_20_2) {
4509             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4510             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4511             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4512             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4513         }
4514
4515         hr = IDirect3DDevice9_EndScene(device);
4516         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4517     }
4518     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4519     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4520
4521     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4522     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4523     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4524     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4525
4526     color = getPixelColor(device, 160, 360);
4527     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4528        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4529     color = getPixelColor(device, 480, 360);
4530     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4531        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4532     if(shader_20) {
4533         color = getPixelColor(device, 160, 120);
4534         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4535            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4536     }
4537     if(shader_20_2) {
4538         color = getPixelColor(device, 480, 120);
4539         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4540            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4541     }
4542
4543     IDirect3DVertexDeclaration9_Release(decl);
4544     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4545     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4546     IDirect3DVertexShader9_Release(shader_11_2);
4547     IDirect3DVertexShader9_Release(shader_11);
4548 }
4549
4550 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4551 {
4552     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4553     HRESULT hr;
4554     DWORD color;
4555     DWORD shader_code_11[] =  {
4556         0xffff0101,                                         /* ps_1_1           */
4557         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4558         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4559         0x0000ffff                                          /* end              */
4560     };
4561     DWORD shader_code_12[] =  {
4562         0xffff0102,                                         /* ps_1_2           */
4563         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4564         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4565         0x0000ffff                                          /* end              */
4566     };
4567     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4568      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4569      * During development of this test, 1.3 shaders were verified too
4570      */
4571     DWORD shader_code_14[] =  {
4572         0xffff0104,                                         /* ps_1_4           */
4573         /* Try to make one constant local. It gets clamped too, although the binary contains
4574          * the bigger numbers
4575          */
4576         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4577         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4578         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4579         0x0000ffff                                          /* end              */
4580     };
4581     DWORD shader_code_20[] =  {
4582         0xffff0200,                                         /* ps_2_0           */
4583         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4584         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4585         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4586         0x0000ffff                                          /* end              */
4587     };
4588     float quad1[] = {
4589         -1.0,   -1.0,   0.1,
4590          0.0,   -1.0,   0.1,
4591         -1.0,    0.0,   0.1,
4592          0.0,    0.0,   0.1
4593     };
4594     float quad2[] = {
4595          0.0,   -1.0,   0.1,
4596          1.0,   -1.0,   0.1,
4597          0.0,    0.0,   0.1,
4598          1.0,    0.0,   0.1
4599     };
4600     float quad3[] = {
4601          0.0,    0.0,   0.1,
4602          1.0,    0.0,   0.1,
4603          0.0,    1.0,   0.1,
4604          1.0,    1.0,   0.1
4605     };
4606     float quad4[] = {
4607         -1.0,    0.0,   0.1,
4608          0.0,    0.0,   0.1,
4609         -1.0,    1.0,   0.1,
4610          0.0,    1.0,   0.1
4611     };
4612     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4613     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4614
4615     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4616     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4617
4618     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4619     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4620     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4621     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4622     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4623     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4624     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4625     if(FAILED(hr)) shader_20 = NULL;
4626
4627     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4628     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4629     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4630     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4631     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4632     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4633
4634     hr = IDirect3DDevice9_BeginScene(device);
4635     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4636     if(SUCCEEDED(hr))
4637     {
4638         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4639         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4641         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4642
4643         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4644         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4645         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4646         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4647
4648         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4649         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4650         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4651         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4652
4653         if(shader_20) {
4654             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4655             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4656             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4657             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4658         }
4659
4660         hr = IDirect3DDevice9_EndScene(device);
4661         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4662     }
4663     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4664     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4665
4666     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4667     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4668
4669     color = getPixelColor(device, 160, 360);
4670     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4671        "quad 1 has color %08x, expected 0x00808000\n", color);
4672     color = getPixelColor(device, 480, 360);
4673     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4674        "quad 2 has color %08x, expected 0x00808000\n", color);
4675     color = getPixelColor(device, 480, 120);
4676     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4677        "quad 3 has color %08x, expected 0x00808000\n", color);
4678     if(shader_20) {
4679         color = getPixelColor(device, 160, 120);
4680         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4681            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4682     }
4683
4684     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4685     IDirect3DPixelShader9_Release(shader_14);
4686     IDirect3DPixelShader9_Release(shader_12);
4687     IDirect3DPixelShader9_Release(shader_11);
4688 }
4689
4690 static void dp2add_ps_test(IDirect3DDevice9 *device)
4691 {
4692     IDirect3DPixelShader9 *shader_dp2add = NULL;
4693     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4694     HRESULT hr;
4695     DWORD color;
4696
4697     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4698      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4699      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4700      * r0 first.
4701      * The result here for the r,g,b components should be roughly 0.5:
4702      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4703     static const DWORD shader_code_dp2add[] =  {
4704         0xffff0200,                                                             /* ps_2_0                       */
4705         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4706
4707         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4708         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4709
4710         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4711         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4712         0x0000ffff                                                              /* end                          */
4713     };
4714
4715     /* Test the _sat modifier, too.  Result here should be:
4716      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4717      *      _SAT: ==> 1.0
4718      *   ADD: (1.0 + -0.5) = 0.5
4719      */
4720     static const DWORD shader_code_dp2add_sat[] =  {
4721         0xffff0200,                                                             /* ps_2_0                           */
4722         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4723
4724         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4725         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4726         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4727
4728         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4729         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4730         0x0000ffff                                                              /* end                              */
4731     };
4732
4733     const float quad[] = {
4734         -1.0,   -1.0,   0.1,
4735          1.0,   -1.0,   0.1,
4736         -1.0,    1.0,   0.1,
4737          1.0,    1.0,   0.1
4738     };
4739
4740
4741     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4742     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4743
4744     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4749
4750     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4751     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4752
4753     if (shader_dp2add) {
4754
4755         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4756         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4757
4758         hr = IDirect3DDevice9_BeginScene(device);
4759         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4760         if(SUCCEEDED(hr))
4761         {
4762             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4763             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4764
4765             hr = IDirect3DDevice9_EndScene(device);
4766             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4767         }
4768         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4769         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4770
4771         color = getPixelColor(device, 360, 240);
4772         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4773                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4774
4775         IDirect3DPixelShader9_Release(shader_dp2add);
4776     } else {
4777         skip("dp2add shader creation failed\n");
4778     }
4779
4780     if (shader_dp2add_sat) {
4781
4782         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4783         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4784
4785         hr = IDirect3DDevice9_BeginScene(device);
4786         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4787         if(SUCCEEDED(hr))
4788         {
4789             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4790             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791
4792             hr = IDirect3DDevice9_EndScene(device);
4793             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4794         }
4795         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4796         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4797
4798         color = getPixelColor(device, 360, 240);
4799         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4800                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4801
4802         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4803     } else {
4804         skip("dp2add shader creation failed\n");
4805     }
4806
4807     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4808     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4809 }
4810
4811 static void cnd_test(IDirect3DDevice9 *device)
4812 {
4813     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4814     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4815     HRESULT hr;
4816     DWORD color;
4817     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4818      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4819      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4820      */
4821     DWORD shader_code_11[] =  {
4822         0xffff0101,                                                                 /* ps_1_1               */
4823         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4824         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4825         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4826         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4827         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4828         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4829         0x0000ffff                                                                  /* end                  */
4830     };
4831     DWORD shader_code_12[] =  {
4832         0xffff0102,                                                                 /* ps_1_2               */
4833         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4834         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4835         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4836         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4837         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4838         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4839         0x0000ffff                                                                  /* end                  */
4840     };
4841     DWORD shader_code_13[] =  {
4842         0xffff0103,                                                                 /* ps_1_3               */
4843         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4844         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4845         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4846         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4847         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4848         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4849         0x0000ffff                                                                  /* end                  */
4850     };
4851     DWORD shader_code_14[] =  {
4852         0xffff0104,                                                                 /* ps_1_3               */
4853         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4854         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4855         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4856         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4857         0x0000ffff                                                                  /* end                  */
4858     };
4859
4860     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4861      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4862      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4863      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4864      * native CreatePixelShader returns an error.
4865      *
4866      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4867      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4868      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4869      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4870      */
4871     DWORD shader_code_11_coissue[] =  {
4872         0xffff0101,                                                             /* ps_1_1                   */
4873         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4874         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4875         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4876         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4877         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4878         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4879         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4880         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4881         /* 0x40000000 = D3DSI_COISSUE */
4882         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4883         0x0000ffff                                                              /* end                      */
4884     };
4885     DWORD shader_code_12_coissue[] =  {
4886         0xffff0102,                                                             /* ps_1_2                   */
4887         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4888         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4889         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4890         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4891         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4892         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4893         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4894         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4895         /* 0x40000000 = D3DSI_COISSUE */
4896         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4897         0x0000ffff                                                              /* end                      */
4898     };
4899     DWORD shader_code_13_coissue[] =  {
4900         0xffff0103,                                                             /* ps_1_3                   */
4901         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4902         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4903         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4904         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4905         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4906         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4907         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4908         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4909         /* 0x40000000 = D3DSI_COISSUE */
4910         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4911         0x0000ffff                                                              /* end                      */
4912     };
4913     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4914      * compare against 0.5
4915      */
4916     DWORD shader_code_14_coissue[] =  {
4917         0xffff0104,                                                             /* ps_1_4                   */
4918         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4919         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4920         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4921         /* 0x40000000 = D3DSI_COISSUE */
4922         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4923         0x0000ffff                                                              /* end                      */
4924     };
4925     float quad1[] = {
4926         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4927          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4928         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4929          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4930     };
4931     float quad2[] = {
4932          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4933          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4934          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4935          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4936     };
4937     float quad3[] = {
4938          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4939          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4940          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4941          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4942     };
4943     float quad4[] = {
4944         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4945          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4946         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4947          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4948     };
4949     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4950     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4951     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4952     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4953
4954     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4955     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4956
4957     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4958     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4959     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4960     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4961     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4962     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4963     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4964     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4965     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4966     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4967     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4968     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4969     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4970     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4971     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4972     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4973
4974     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4975     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4976     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4977     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4978     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4979     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4980
4981     hr = IDirect3DDevice9_BeginScene(device);
4982     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4983     if(SUCCEEDED(hr))
4984     {
4985         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4986         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4987         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4988         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4989
4990         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4991         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4993         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4994
4995         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4996         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4997         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4998         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4999
5000         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5001         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5002         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5003         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5004
5005         hr = IDirect3DDevice9_EndScene(device);
5006         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5007     }
5008     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5009     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5010
5011     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5012     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5013
5014     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5015     color = getPixelColor(device, 158, 118);
5016     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5017     color = getPixelColor(device, 162, 118);
5018     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5019     color = getPixelColor(device, 158, 122);
5020     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5021     color = getPixelColor(device, 162, 122);
5022     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5023
5024     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5025     color = getPixelColor(device, 158, 358);
5026     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5027     color = getPixelColor(device, 162, 358);
5028     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5029         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5030     color = getPixelColor(device, 158, 362);
5031     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5032     color = getPixelColor(device, 162, 362);
5033     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5034         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5035
5036     /* 1.2 shader */
5037     color = getPixelColor(device, 478, 358);
5038     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5039     color = getPixelColor(device, 482, 358);
5040     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5041         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5042     color = getPixelColor(device, 478, 362);
5043     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5044     color = getPixelColor(device, 482, 362);
5045     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5046         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5047
5048     /* 1.3 shader */
5049     color = getPixelColor(device, 478, 118);
5050     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5051     color = getPixelColor(device, 482, 118);
5052     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5053         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5054     color = getPixelColor(device, 478, 122);
5055     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5056     color = getPixelColor(device, 482, 122);
5057     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5058         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5059
5060     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5061     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5062     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5064     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5065     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5066
5067     hr = IDirect3DDevice9_BeginScene(device);
5068     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5069     if(SUCCEEDED(hr))
5070     {
5071         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5072         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5073         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5074         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5075
5076         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5077         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5078         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5079         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5080
5081         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5082         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5083         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5084         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5085
5086         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5087         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5088         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5089         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5090
5091         hr = IDirect3DDevice9_EndScene(device);
5092         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5093     }
5094     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5095     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5096
5097     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5098     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5099
5100     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5101      * that we swapped the values in c1 and c2 to make the other tests return some color
5102      */
5103     color = getPixelColor(device, 158, 118);
5104     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5105     color = getPixelColor(device, 162, 118);
5106     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5107     color = getPixelColor(device, 158, 122);
5108     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5109     color = getPixelColor(device, 162, 122);
5110     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5111
5112     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5113     color = getPixelColor(device, 158, 358);
5114     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5115         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5116     color = getPixelColor(device, 162, 358);
5117     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5118         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5119     color = getPixelColor(device, 158, 362);
5120     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5121         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5122     color = getPixelColor(device, 162, 362);
5123     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5124         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5125
5126     /* 1.2 shader */
5127     color = getPixelColor(device, 478, 358);
5128     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5129         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5130     color = getPixelColor(device, 482, 358);
5131     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5132         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5133     color = getPixelColor(device, 478, 362);
5134     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5135         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5136     color = getPixelColor(device, 482, 362);
5137     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5138         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5139
5140     /* 1.3 shader */
5141     color = getPixelColor(device, 478, 118);
5142     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5143         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5144     color = getPixelColor(device, 482, 118);
5145     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5146         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5147     color = getPixelColor(device, 478, 122);
5148     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5149         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5150     color = getPixelColor(device, 482, 122);
5151     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5152         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5153
5154     IDirect3DPixelShader9_Release(shader_14_coissue);
5155     IDirect3DPixelShader9_Release(shader_13_coissue);
5156     IDirect3DPixelShader9_Release(shader_12_coissue);
5157     IDirect3DPixelShader9_Release(shader_11_coissue);
5158     IDirect3DPixelShader9_Release(shader_14);
5159     IDirect3DPixelShader9_Release(shader_13);
5160     IDirect3DPixelShader9_Release(shader_12);
5161     IDirect3DPixelShader9_Release(shader_11);
5162 }
5163
5164 static void nested_loop_test(IDirect3DDevice9 *device) {
5165     const DWORD shader_code[] = {
5166         0xffff0300,                                                             /* ps_3_0               */
5167         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5168         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5169         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5170         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5171         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5172         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5173         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5174         0x0000001d,                                                             /* endloop              */
5175         0x0000001d,                                                             /* endloop              */
5176         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5177         0x0000ffff                                                              /* end                  */
5178     };
5179     IDirect3DPixelShader9 *shader;
5180     HRESULT hr;
5181     DWORD color;
5182     const float quad[] = {
5183         -1.0,   -1.0,   0.1,
5184          1.0,   -1.0,   0.1,
5185         -1.0,    1.0,   0.1,
5186          1.0,    1.0,   0.1
5187     };
5188
5189     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5190     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5191     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5192     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5193     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5194     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5195     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5196     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5197
5198     hr = IDirect3DDevice9_BeginScene(device);
5199     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5200     if(SUCCEEDED(hr))
5201     {
5202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5203         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5204         hr = IDirect3DDevice9_EndScene(device);
5205         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5206     }
5207     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5208     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5209
5210     color = getPixelColor(device, 360, 240);
5211     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5212        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5213
5214     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5215     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5216     IDirect3DPixelShader9_Release(shader);
5217 }
5218
5219 struct varying_test_struct
5220 {
5221     const DWORD             *shader_code;
5222     IDirect3DPixelShader9   *shader;
5223     DWORD                   color, color_rhw;
5224     const char              *name;
5225     BOOL                    todo, todo_rhw;
5226 };
5227
5228 struct hugeVertex
5229 {
5230     float pos_x,        pos_y,      pos_z,      rhw;
5231     float weight_1,     weight_2,   weight_3,   weight_4;
5232     float index_1,      index_2,    index_3,    index_4;
5233     float normal_1,     normal_2,   normal_3,   normal_4;
5234     float fog_1,        fog_2,      fog_3,      fog_4;
5235     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5236     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5237     float binormal_1,   binormal_2, binormal_3, binormal_4;
5238     float depth_1,      depth_2,    depth_3,    depth_4;
5239     DWORD diffuse, specular;
5240 };
5241
5242 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5243     /* dcl_position: fails to compile */
5244     const DWORD blendweight_code[] = {
5245         0xffff0300,                             /* ps_3_0                   */
5246         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5247         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5248         0x0000ffff                              /* end                      */
5249     };
5250     const DWORD blendindices_code[] = {
5251         0xffff0300,                             /* ps_3_0                   */
5252         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5253         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5254         0x0000ffff                              /* end                      */
5255     };
5256     const DWORD normal_code[] = {
5257         0xffff0300,                             /* ps_3_0                   */
5258         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5259         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5260         0x0000ffff                              /* end                      */
5261     };
5262     /* psize: fails? */
5263     const DWORD texcoord0_code[] = {
5264         0xffff0300,                             /* ps_3_0                   */
5265         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5266         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5267         0x0000ffff                              /* end                      */
5268     };
5269     const DWORD tangent_code[] = {
5270         0xffff0300,                             /* ps_3_0                   */
5271         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5272         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5273         0x0000ffff                              /* end                      */
5274     };
5275     const DWORD binormal_code[] = {
5276         0xffff0300,                             /* ps_3_0                   */
5277         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5278         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5279         0x0000ffff                              /* end                      */
5280     };
5281     /* tessfactor: fails */
5282     /* positiont: fails */
5283     const DWORD color_code[] = {
5284         0xffff0300,                             /* ps_3_0                   */
5285         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5286         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5287         0x0000ffff                              /* end                      */
5288     };
5289     const DWORD fog_code[] = {
5290         0xffff0300,                             /* ps_3_0                   */
5291         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5292         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5293         0x0000ffff                              /* end                      */
5294     };
5295     const DWORD depth_code[] = {
5296         0xffff0300,                             /* ps_3_0                   */
5297         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5298         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5299         0x0000ffff                              /* end                      */
5300     };
5301     const DWORD specular_code[] = {
5302         0xffff0300,                             /* ps_3_0                   */
5303         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5304         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5305         0x0000ffff                              /* end                      */
5306     };
5307     /* sample: fails */
5308
5309     struct varying_test_struct tests[] = {
5310        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5311        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5312        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5313        /* Why does dx not forward the texcoord? */
5314        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5315        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5316        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5317        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5318        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5319        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5320        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5321     };
5322     /* Declare a monster vertex type :-) */
5323     static const D3DVERTEXELEMENT9 decl_elements[] = {
5324         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5325         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5326         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5327         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5328         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5329         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5330         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5331         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5332         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5333         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5334         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5335         D3DDECL_END()
5336     };
5337     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5338         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5339         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5340         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5341         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5342         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5343         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5344         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5345         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5346         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5347         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5348         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5349         D3DDECL_END()
5350     };
5351     struct hugeVertex data[4] = {
5352         {
5353             -1.0,   -1.0,   0.1,    1.0,
5354              0.1,    0.1,   0.1,    0.1,
5355              0.2,    0.2,   0.2,    0.2,
5356              0.3,    0.3,   0.3,    0.3,
5357              0.4,    0.4,   0.4,    0.4,
5358              0.50,   0.55,  0.55,   0.55,
5359              0.6,    0.6,   0.6,    0.7,
5360              0.7,    0.7,   0.7,    0.6,
5361              0.8,    0.8,   0.8,    0.8,
5362              0xe6e6e6e6, /* 0.9 * 256 */
5363              0x224488ff  /* Nothing special */
5364         },
5365         {
5366              1.0,   -1.0,   0.1,    1.0,
5367              0.1,    0.1,   0.1,    0.1,
5368              0.2,    0.2,   0.2,    0.2,
5369              0.3,    0.3,   0.3,    0.3,
5370              0.4,    0.4,   0.4,    0.4,
5371              0.50,   0.55,  0.55,   0.55,
5372              0.6,    0.6,   0.6,    0.7,
5373              0.7,    0.7,   0.7,    0.6,
5374              0.8,    0.8,   0.8,    0.8,
5375              0xe6e6e6e6, /* 0.9 * 256 */
5376              0x224488ff /* Nothing special */
5377         },
5378         {
5379             -1.0,    1.0,   0.1,    1.0,
5380              0.1,    0.1,   0.1,    0.1,
5381              0.2,    0.2,   0.2,    0.2,
5382              0.3,    0.3,   0.3,    0.3,
5383              0.4,    0.4,   0.4,    0.4,
5384              0.50,   0.55,  0.55,   0.55,
5385              0.6,    0.6,   0.6,    0.7,
5386              0.7,    0.7,   0.7,    0.6,
5387              0.8,    0.8,   0.8,    0.8,
5388              0xe6e6e6e6, /* 0.9 * 256 */
5389              0x224488ff /* Nothing special */
5390         },
5391         {
5392              1.0,    1.0,   0.1,    1.0,
5393              0.1,    0.1,   0.1,    0.1,
5394              0.2,    0.2,   0.2,    0.2,
5395              0.3,    0.3,   0.3,    0.3,
5396              0.4,    0.4,   0.4,    0.4,
5397              0.50,   0.55,  0.55,   0.55,
5398              0.6,    0.6,   0.6,    0.7,
5399              0.7,    0.7,   0.7,    0.6,
5400              0.8,    0.8,   0.8,    0.8,
5401              0xe6e6e6e6, /* 0.9 * 256 */
5402              0x224488ff /* Nothing special */
5403         },
5404     };
5405     struct hugeVertex data2[4];
5406     IDirect3DVertexDeclaration9 *decl;
5407     IDirect3DVertexDeclaration9 *decl2;
5408     HRESULT hr;
5409     unsigned int i;
5410     DWORD color, r, g, b, r_e, g_e, b_e;
5411     BOOL drawok;
5412
5413     memcpy(data2, data, sizeof(data2));
5414     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5415     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5416     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5417     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5418
5419     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5420     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5421     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5422     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5423     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5424     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5425
5426     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5427     {
5428         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5429         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5430            tests[i].name, hr);
5431     }
5432
5433     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5434     {
5435         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5436         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5437
5438         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5439         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5440
5441         hr = IDirect3DDevice9_BeginScene(device);
5442         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5443         drawok = FALSE;
5444         if(SUCCEEDED(hr))
5445         {
5446             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5447             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5448             drawok = SUCCEEDED(hr);
5449             hr = IDirect3DDevice9_EndScene(device);
5450             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5451         }
5452         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5453         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5454
5455         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5456          * the failure and do not check the color if it failed
5457          */
5458         if(!drawok) {
5459             continue;
5460         }
5461
5462         color = getPixelColor(device, 360, 240);
5463         r = color & 0x00ff0000 >> 16;
5464         g = color & 0x0000ff00 >>  8;
5465         b = color & 0x000000ff;
5466         r_e = tests[i].color & 0x00ff0000 >> 16;
5467         g_e = tests[i].color & 0x0000ff00 >>  8;
5468         b_e = tests[i].color & 0x000000ff;
5469
5470         if(tests[i].todo) {
5471             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5472                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5473                          tests[i].name, color, tests[i].color);
5474         } else {
5475             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5476                "Test %s returned color 0x%08x, expected 0x%08x\n",
5477                tests[i].name, color, tests[i].color);
5478         }
5479     }
5480
5481     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5482     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5483     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5484     {
5485         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5486         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5487
5488         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5489         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5490
5491         hr = IDirect3DDevice9_BeginScene(device);
5492         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5493         if(SUCCEEDED(hr))
5494         {
5495             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5496             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5497             hr = IDirect3DDevice9_EndScene(device);
5498             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5499         }
5500         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5501         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5502
5503         color = getPixelColor(device, 360, 240);
5504         r = color & 0x00ff0000 >> 16;
5505         g = color & 0x0000ff00 >>  8;
5506         b = color & 0x000000ff;
5507         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5508         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5509         b_e = tests[i].color_rhw & 0x000000ff;
5510
5511         if(tests[i].todo_rhw) {
5512             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5513              * pipeline
5514              */
5515             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5516                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5517                          tests[i].name, color, tests[i].color_rhw);
5518         } else {
5519             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5520                "Test %s returned color 0x%08x, expected 0x%08x\n",
5521                tests[i].name, color, tests[i].color_rhw);
5522         }
5523     }
5524
5525     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5526     {
5527         IDirect3DPixelShader9_Release(tests[i].shader);
5528     }
5529
5530     IDirect3DVertexDeclaration9_Release(decl2);
5531     IDirect3DVertexDeclaration9_Release(decl);
5532 }
5533
5534 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5535     static const DWORD ps_code[] = {
5536     0xffff0300,                                                             /* ps_3_0                       */
5537     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5538     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5539     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5540     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5541     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5542     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5543     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5544     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5545     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5546
5547     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5548     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5549     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5550     0x0000001d,                                                             /* endloop                      */
5551     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5552     0x0000ffff                                                              /* end                          */
5553     };
5554     static const DWORD vs_1_code[] = {
5555     0xfffe0101,                                                             /* vs_1_1                       */
5556     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5557     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5558     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5559     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5560     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5561     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5562     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5563     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5564     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5565     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5566     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5567     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5568     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5569     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5570     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5571     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5572     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5573     0x0000ffff
5574     };
5575     DWORD vs_2_code[] = {
5576     0xfffe0200,                                                             /* vs_2_0                       */
5577     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5578     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5579     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5580     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5581     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5582     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5583     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5584     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5585     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5586     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5587     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5588     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5589     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5590     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5591     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5592     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5593     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5594     0x0000ffff                                                              /* end                          */
5595     };
5596     /* TODO: Define normal, tangent, blendweight and depth here */
5597     static const DWORD vs_3_code[] = {
5598     0xfffe0300,                                                             /* vs_3_0                       */
5599     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5600     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5601     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5602     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5603     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5604     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5605     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5606     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5607     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5608     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5609     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5610     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5611     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5612     0x0000ffff                                                              /* end                          */
5613     };
5614     float quad1[] =  {
5615         -1.0,   -1.0,   0.1,
5616          0.0,   -1.0,   0.1,
5617         -1.0,    0.0,   0.1,
5618          0.0,    0.0,   0.1
5619     };
5620     float quad2[] =  {
5621          0.0,   -1.0,   0.1,
5622          1.0,   -1.0,   0.1,
5623          0.0,    0.0,   0.1,
5624          1.0,    0.0,   0.1
5625     };
5626     float quad3[] =  {
5627         -1.0,    0.0,   0.1,
5628          0.0,    0.0,   0.1,
5629         -1.0,    1.0,   0.1,
5630          0.0,    1.0,   0.1
5631     };
5632
5633     HRESULT hr;
5634     DWORD color;
5635     IDirect3DPixelShader9 *pixelshader = NULL;
5636     IDirect3DVertexShader9 *vs_1_shader = NULL;
5637     IDirect3DVertexShader9 *vs_2_shader = NULL;
5638     IDirect3DVertexShader9 *vs_3_shader = NULL;
5639
5640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5641     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5642
5643     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5644     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5645     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5646     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5647     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5648     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5649     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5650     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5651     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5652     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5653     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5654
5655     hr = IDirect3DDevice9_BeginScene(device);
5656     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5657     if(SUCCEEDED(hr))
5658     {
5659         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5660         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5661         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5662         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5663
5664         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5665         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5666         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5667         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5668
5669         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5670         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5672         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5673
5674         hr = IDirect3DDevice9_EndScene(device);
5675         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5676     }
5677     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5678     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5679
5680     color = getPixelColor(device, 160, 120);
5681     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5682        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5683     /* Accept two ways of oFog handling:
5684      *
5685      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5686      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5687      *
5688      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5689      *    This happens with software vertex processing and on Intel cards
5690      *
5691      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5692      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5693      */
5694     color = getPixelColor(device, 160, 360);
5695     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5696        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5697        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5698     color = getPixelColor(device, 480, 360);
5699     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5700        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5701        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5702
5703     /* cleanup */
5704     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5705     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5706     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5707     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5708     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5709     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5710     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5711     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5712 }
5713
5714 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5715     static const DWORD vs_code[] = {
5716     0xfffe0300,                                                             /* vs_3_0                       */
5717     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5718     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5719     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5720     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5721     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5722     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5723     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5724     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5725     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5726     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5727     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5728     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5729     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5730
5731     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5732     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5733     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5734     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5735     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5736     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5737     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5738     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5739     0x0000ffff                                                              /* end                          */
5740     };
5741     static const DWORD ps_1_code[] = {
5742     0xffff0104,                                                             /* ps_1_4                       */
5743     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5744     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5745     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5746     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5747     0x0000ffff                                                              /* end                          */
5748     };
5749     static const DWORD ps_2_code[] = {
5750     0xffff0200,                                                             /* ps_2_0                       */
5751     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5752     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5753     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5754
5755     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5756     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5757     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5758     0x0000ffff                                                              /* end                          */
5759     };
5760     static const DWORD ps_3_code[] = {
5761     0xffff0300,                                                             /* ps_3_0                       */
5762     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5763     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5764     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5765
5766     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5767     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5768     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5769     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5770     0x0000ffff                                                              /* end                          */
5771     };
5772
5773     float quad1[] =  {
5774         -1.0,   -1.0,   0.1,
5775          0.0,   -1.0,   0.1,
5776         -1.0,    0.0,   0.1,
5777          0.0,    0.0,   0.1
5778     };
5779     float quad2[] =  {
5780          0.0,   -1.0,   0.1,
5781          1.0,   -1.0,   0.1,
5782          0.0,    0.0,   0.1,
5783          1.0,    0.0,   0.1
5784     };
5785     float quad3[] =  {
5786         -1.0,    0.0,   0.1,
5787          0.0,    0.0,   0.1,
5788         -1.0,    1.0,   0.1,
5789          0.0,    1.0,   0.1
5790     };
5791     float quad4[] =  {
5792          0.0,    0.0,   0.1,
5793          1.0,    0.0,   0.1,
5794          0.0,    1.0,   0.1,
5795          1.0,    1.0,   0.1
5796     };
5797
5798     HRESULT hr;
5799     DWORD color;
5800     IDirect3DVertexShader9 *vertexshader = NULL;
5801     IDirect3DPixelShader9 *ps_1_shader = NULL;
5802     IDirect3DPixelShader9 *ps_2_shader = NULL;
5803     IDirect3DPixelShader9 *ps_3_shader = NULL;
5804     IDirect3DTexture9 *texture = NULL;
5805     D3DLOCKED_RECT lr;
5806     unsigned int x, y;
5807
5808     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5809     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5810
5811     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5812     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5813     if(FAILED(hr)) {
5814         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5815         return;
5816     }
5817     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5818     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5819     for(y = 0; y < 512; y++) {
5820         for(x = 0; x < 512; x++) {
5821             double r_f = (double) x / (double) 512;
5822             double g_f = (double) y / (double) 512;
5823             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5824             unsigned short r = (unsigned short) (r_f * 65535.0);
5825             unsigned short g = (unsigned short) (g_f * 65535.0);
5826             dst[0] = r;
5827             dst[1] = g;
5828             dst[2] = 0;
5829             dst[3] = 65535;
5830         }
5831     }
5832     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5833     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5834
5835     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5836     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5837     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5838     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5839     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5840     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5841     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5842     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5843     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5844     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5845     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5846
5847     hr = IDirect3DDevice9_BeginScene(device);
5848     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5849     if(SUCCEEDED(hr))
5850     {
5851         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5852         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5853         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5854         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5855
5856         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5857         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5858         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5859         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5860
5861         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5862         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5863         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5864         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5865
5866         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5867         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5868         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5869         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5870         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5871         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5872         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5873         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5874         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5875         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5876         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5877         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5878         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5879         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5880
5881         hr = IDirect3DDevice9_EndScene(device);
5882         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5883     }
5884     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5885     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5886
5887     color = getPixelColor(device, 160, 120);
5888     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5889        (color & 0x0000ff00) == 0x0000ff00 &&
5890        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5891        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5892     color = getPixelColor(device, 160, 360);
5893     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5894        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5895        (color & 0x000000ff) == 0x00000000,
5896        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5897     color = getPixelColor(device, 480, 360);
5898     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5899        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5900        (color & 0x000000ff) == 0x00000000,
5901        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5902     color = getPixelColor(device, 480, 160);
5903     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5904        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5905        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5906        (color & 0x000000ff) == 0x00000000),
5907        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5908
5909     /* cleanup */
5910     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5911     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5912     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5913     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5914     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5915     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5916     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5917     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5918     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5919     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5920     if(texture) IDirect3DTexture9_Release(texture);
5921 }
5922
5923 static void test_compare_instructions(IDirect3DDevice9 *device)
5924 {
5925     DWORD shader_sge_vec_code[] = {
5926         0xfffe0101,                                         /* vs_1_1                   */
5927         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5928         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5929         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5930         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5931         0x0000ffff                                          /* end                      */
5932     };
5933     DWORD shader_slt_vec_code[] = {
5934         0xfffe0101,                                         /* vs_1_1                   */
5935         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5936         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5937         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5938         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5939         0x0000ffff                                          /* end                      */
5940     };
5941     DWORD shader_sge_scalar_code[] = {
5942         0xfffe0101,                                         /* vs_1_1                   */
5943         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5944         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5945         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5946         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5947         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5948         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5949         0x0000ffff                                          /* end                      */
5950     };
5951     DWORD shader_slt_scalar_code[] = {
5952         0xfffe0101,                                         /* vs_1_1                   */
5953         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5954         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5955         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5956         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5957         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5958         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5959         0x0000ffff                                          /* end                      */
5960     };
5961     IDirect3DVertexShader9 *shader_sge_vec;
5962     IDirect3DVertexShader9 *shader_slt_vec;
5963     IDirect3DVertexShader9 *shader_sge_scalar;
5964     IDirect3DVertexShader9 *shader_slt_scalar;
5965     HRESULT hr, color;
5966     float quad1[] =  {
5967         -1.0,   -1.0,   0.1,
5968          0.0,   -1.0,   0.1,
5969         -1.0,    0.0,   0.1,
5970          0.0,    0.0,   0.1
5971     };
5972     float quad2[] =  {
5973          0.0,   -1.0,   0.1,
5974          1.0,   -1.0,   0.1,
5975          0.0,    0.0,   0.1,
5976          1.0,    0.0,   0.1
5977     };
5978     float quad3[] =  {
5979         -1.0,    0.0,   0.1,
5980          0.0,    0.0,   0.1,
5981         -1.0,    1.0,   0.1,
5982          0.0,    1.0,   0.1
5983     };
5984     float quad4[] =  {
5985          0.0,    0.0,   0.1,
5986          1.0,    0.0,   0.1,
5987          0.0,    1.0,   0.1,
5988          1.0,    1.0,   0.1
5989     };
5990     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5991     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5992
5993     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5994     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5995
5996     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5997     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5998     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5999     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6000     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6001     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6002     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6003     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6004     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6005     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6006     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6007     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6008     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6009     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6010
6011     hr = IDirect3DDevice9_BeginScene(device);
6012     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6013     if(SUCCEEDED(hr))
6014     {
6015         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6016         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6017         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6018         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6019
6020         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6021         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6022         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6023         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6024
6025         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6026         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6027         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6028         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6029
6030         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6031         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6032
6033         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6034         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6035         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6036         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6037
6038         hr = IDirect3DDevice9_EndScene(device);
6039         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6040     }
6041
6042     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6043     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6044     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6045     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6046
6047     color = getPixelColor(device, 160, 360);
6048     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6049     color = getPixelColor(device, 480, 360);
6050     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6051     color = getPixelColor(device, 160, 120);
6052     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6053     color = getPixelColor(device, 480, 160);
6054     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6055
6056     IDirect3DVertexShader9_Release(shader_sge_vec);
6057     IDirect3DVertexShader9_Release(shader_slt_vec);
6058     IDirect3DVertexShader9_Release(shader_sge_scalar);
6059     IDirect3DVertexShader9_Release(shader_slt_scalar);
6060 }
6061
6062 static void test_vshader_input(IDirect3DDevice9 *device)
6063 {
6064     DWORD swapped_shader_code_3[] = {
6065         0xfffe0300,                                         /* vs_3_0               */
6066         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6067         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6068         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6069         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6070         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6071         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6072         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6073         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6074         0x0000ffff                                          /* end                  */
6075     };
6076     DWORD swapped_shader_code_1[] = {
6077         0xfffe0101,                                         /* vs_1_1               */
6078         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6079         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6080         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6081         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6082         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6083         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6084         0x0000ffff                                          /* end                  */
6085     };
6086     DWORD swapped_shader_code_2[] = {
6087         0xfffe0200,                                         /* vs_2_0               */
6088         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6089         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6090         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6091         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6092         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6093         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6094         0x0000ffff                                          /* end                  */
6095     };
6096     DWORD texcoord_color_shader_code_3[] = {
6097         0xfffe0300,                                         /* vs_3_0               */
6098         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6099         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6100         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6101         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6102         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6103         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6104         0x0000ffff                                          /* end                  */
6105     };
6106     DWORD texcoord_color_shader_code_2[] = {
6107         0xfffe0200,                                         /* vs_2_0               */
6108         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6109         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6110         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6111         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6112         0x0000ffff                                          /* end                  */
6113     };
6114     DWORD texcoord_color_shader_code_1[] = {
6115         0xfffe0101,                                         /* vs_1_1               */
6116         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6117         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6118         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6119         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6120         0x0000ffff                                          /* end                  */
6121     };
6122     DWORD color_color_shader_code_3[] = {
6123         0xfffe0300,                                         /* vs_3_0               */
6124         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6125         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6126         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6127         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6128         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6129         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6130         0x0000ffff                                          /* end                  */
6131     };
6132     DWORD color_color_shader_code_2[] = {
6133         0xfffe0200,                                         /* vs_2_0               */
6134         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6135         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6136         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6137         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6138         0x0000ffff                                          /* end                  */
6139     };
6140     DWORD color_color_shader_code_1[] = {
6141         0xfffe0101,                                         /* vs_1_1               */
6142         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6143         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6144         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6145         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6146         0x0000ffff                                          /* end                  */
6147     };
6148     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6149     HRESULT hr;
6150     DWORD color;
6151     float quad1[] =  {
6152         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6153          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6154         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6155          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6156     };
6157     float quad2[] =  {
6158          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6159          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6160          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6161          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6162     };
6163     float quad3[] =  {
6164         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6165          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6166         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6167          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6168     };
6169     float quad4[] =  {
6170          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6171          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6172          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6173          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6174     };
6175     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6176         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6177         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6178         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6179         D3DDECL_END()
6180     };
6181     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6182         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6183         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6184         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6185         D3DDECL_END()
6186     };
6187     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6188         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6189         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6190         D3DDECL_END()
6191     };
6192     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6193         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6194         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6195         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6196         D3DDECL_END()
6197     };
6198     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6199         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6200         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6201         D3DDECL_END()
6202     };
6203     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6204         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6205         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6206         D3DDECL_END()
6207     };
6208     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6209         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6210         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6211         D3DDECL_END()
6212     };
6213     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6214         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6215         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6216         D3DDECL_END()
6217     };
6218     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6219     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6220     unsigned int i;
6221     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6222     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6223
6224     struct vertex quad1_color[] =  {
6225        {-1.0,   -1.0,   0.1,    0x00ff8040},
6226        { 0.0,   -1.0,   0.1,    0x00ff8040},
6227        {-1.0,    0.0,   0.1,    0x00ff8040},
6228        { 0.0,    0.0,   0.1,    0x00ff8040}
6229     };
6230     struct vertex quad2_color[] =  {
6231        { 0.0,   -1.0,   0.1,    0x00ff8040},
6232        { 1.0,   -1.0,   0.1,    0x00ff8040},
6233        { 0.0,    0.0,   0.1,    0x00ff8040},
6234        { 1.0,    0.0,   0.1,    0x00ff8040}
6235     };
6236     struct vertex quad3_color[] =  {
6237        {-1.0,    0.0,   0.1,    0x00ff8040},
6238        { 0.0,    0.0,   0.1,    0x00ff8040},
6239        {-1.0,    1.0,   0.1,    0x00ff8040},
6240        { 0.0,    1.0,   0.1,    0x00ff8040}
6241     };
6242     float quad4_color[] =  {
6243          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6244          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6245          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6246          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6247     };
6248
6249     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6250     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6251     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6252     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6253     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6254     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6255     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6256     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6257
6258     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6260     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6261     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6262     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6263     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6264     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6265     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6266
6267     for(i = 1; i <= 3; i++) {
6268         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6269         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6270         if(i == 3) {
6271             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6272             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6273         } else if(i == 2){
6274             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6275             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6276         } else if(i == 1) {
6277             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6278             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6279         }
6280
6281         hr = IDirect3DDevice9_BeginScene(device);
6282         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6283         if(SUCCEEDED(hr))
6284         {
6285             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6286             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6287
6288             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6289             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6290             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6291             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6292
6293             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6294             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6295             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6296             if(i == 3 || i == 2) {
6297                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6298             } else if(i == 1) {
6299                 /* Succeeds or fails, depending on SW or HW vertex processing */
6300                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6301             }
6302
6303             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6304             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6305             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6306             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6307
6308             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6309             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6310             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6311             if(i == 3 || i == 2) {
6312                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6313             } else if(i == 1) {
6314                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6315             }
6316
6317             hr = IDirect3DDevice9_EndScene(device);
6318             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6319         }
6320
6321         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6322         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6323
6324         if(i == 3 || i == 2) {
6325             color = getPixelColor(device, 160, 360);
6326             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6327                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6328
6329             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6330             color = getPixelColor(device, 480, 360);
6331             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6332                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6333             color = getPixelColor(device, 160, 120);
6334             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6335             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6336                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6337
6338             color = getPixelColor(device, 480, 160);
6339             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6340         } else if(i == 1) {
6341             color = getPixelColor(device, 160, 360);
6342             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6343                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6344             color = getPixelColor(device, 480, 360);
6345             /* Accept the clear color as well in this case, since SW VP returns an error */
6346             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6347             color = getPixelColor(device, 160, 120);
6348             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6349                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6350             color = getPixelColor(device, 480, 160);
6351             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6352         }
6353
6354         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6355         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6356
6357         /* Now find out if the whole streams are re-read, or just the last active value for the
6358          * vertices is used.
6359          */
6360         hr = IDirect3DDevice9_BeginScene(device);
6361         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6362         if(SUCCEEDED(hr))
6363         {
6364             float quad1_modified[] =  {
6365                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6366                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6367                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6368                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6369             };
6370             float quad2_modified[] =  {
6371                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6372                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6373                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6374                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6375             };
6376
6377             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6378             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6379
6380             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6381             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6382             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6383             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6384
6385             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6386             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6387             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6388             if(i == 3 || i == 2) {
6389                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6390             } else if(i == 1) {
6391                 /* Succeeds or fails, depending on SW or HW vertex processing */
6392                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6393             }
6394
6395             hr = IDirect3DDevice9_EndScene(device);
6396             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6397         }
6398         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6399         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6400
6401         color = getPixelColor(device, 480, 350);
6402         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6403          * as well.
6404          *
6405          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6406          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6407          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6408          * refrast's result.
6409          *
6410          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6411          */
6412         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6413            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6414
6415         IDirect3DDevice9_SetVertexShader(device, NULL);
6416         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6417
6418         IDirect3DVertexShader9_Release(swapped_shader);
6419     }
6420
6421     for(i = 1; i <= 3; i++) {
6422         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6423         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6424         if(i == 3) {
6425             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6426             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6427             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6428             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6429         } else if(i == 2){
6430             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6431             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6432             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6433             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6434         } else if(i == 1) {
6435             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6436             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6437             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6438             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6439         }
6440
6441         hr = IDirect3DDevice9_BeginScene(device);
6442         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6443         if(SUCCEEDED(hr))
6444         {
6445             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6446             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6447             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6448             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6449             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6450             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6451
6452             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6453             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6454
6455             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6456             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6457             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6458             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6459             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6460             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6461
6462             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6463             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6464             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6465             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6466             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6467             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6468
6469             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6470             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6471             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6472             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6473
6474             hr = IDirect3DDevice9_EndScene(device);
6475             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6476         }
6477         IDirect3DDevice9_SetVertexShader(device, NULL);
6478         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6479
6480         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6481         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6482
6483         color = getPixelColor(device, 160, 360);
6484         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6485            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6486         color = getPixelColor(device, 480, 360);
6487         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6488            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6489         color = getPixelColor(device, 160, 120);
6490         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6491            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6492         color = getPixelColor(device, 480, 160);
6493         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6494            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6495
6496         IDirect3DVertexShader9_Release(texcoord_color_shader);
6497         IDirect3DVertexShader9_Release(color_color_shader);
6498     }
6499
6500     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6501     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6502     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6503     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6504
6505     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6506     IDirect3DVertexDeclaration9_Release(decl_color_color);
6507     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6508     IDirect3DVertexDeclaration9_Release(decl_color_float);
6509 }
6510
6511 static void srgbtexture_test(IDirect3DDevice9 *device)
6512 {
6513     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6514      * texture stage state to render a quad using that texture.  The resulting
6515      * color components should be 0x36 (~ 0.21), per this formula:
6516      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6517      * This is true where srgb_color > 0.04045.
6518      */
6519     IDirect3D9 *d3d = NULL;
6520     HRESULT hr;
6521     LPDIRECT3DTEXTURE9 texture = NULL;
6522     LPDIRECT3DSURFACE9 surface = NULL;
6523     D3DLOCKED_RECT lr;
6524     DWORD color;
6525     float quad[] = {
6526         -1.0,       1.0,       0.0,     0.0,    0.0,
6527          1.0,       1.0,       0.0,     1.0,    0.0,
6528         -1.0,      -1.0,       0.0,     0.0,    1.0,
6529          1.0,      -1.0,       0.0,     1.0,    1.0,
6530     };
6531
6532
6533     memset(&lr, 0, sizeof(lr));
6534     IDirect3DDevice9_GetDirect3D(device, &d3d);
6535     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6536                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6537                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6538         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6539         goto out;
6540     }
6541
6542     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6543                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6544                                         &texture, NULL);
6545     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6546     if(!texture) {
6547         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6548         goto out;
6549     }
6550     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6551     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6552
6553     fill_surface(surface, 0xff7f7f7f);
6554     IDirect3DSurface9_Release(surface);
6555
6556     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6557     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6558     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6559     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6560
6561     hr = IDirect3DDevice9_BeginScene(device);
6562     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6563     if(SUCCEEDED(hr))
6564     {
6565         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6566         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6567
6568         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6569         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6570
6571
6572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6574
6575         hr = IDirect3DDevice9_EndScene(device);
6576         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6577     }
6578
6579     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6580     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6581     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6582     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6583
6584     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6585     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6586
6587     color = getPixelColor(device, 320, 240);
6588     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6589
6590 out:
6591     if(texture) IDirect3DTexture9_Release(texture);
6592     IDirect3D9_Release(d3d);
6593 }
6594
6595 static void shademode_test(IDirect3DDevice9 *device)
6596 {
6597     /* Render a quad and try all of the different fixed function shading models. */
6598     HRESULT hr;
6599     DWORD color0, color1;
6600     DWORD color0_gouraud = 0, color1_gouraud = 0;
6601     DWORD shademode = D3DSHADE_FLAT;
6602     DWORD primtype = D3DPT_TRIANGLESTRIP;
6603     LPVOID data = NULL;
6604     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6605     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6606     UINT i, j;
6607     struct vertex quad_strip[] =
6608     {
6609         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6610         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6611         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6612         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6613     };
6614     struct vertex quad_list[] =
6615     {
6616         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6617         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6618         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6619
6620         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6621         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6622         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6623     };
6624
6625     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6626                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6627     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6628     if (FAILED(hr)) goto bail;
6629
6630     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6631                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6632     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6633     if (FAILED(hr)) goto bail;
6634
6635     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6636     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6637
6638     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6639     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6640
6641     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6642     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6643     memcpy(data, quad_strip, sizeof(quad_strip));
6644     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6645     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6646
6647     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6648     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6649     memcpy(data, quad_list, sizeof(quad_list));
6650     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6651     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6652
6653     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6654      * the color fixups we have to do for FLAT shading will be dependent on that. */
6655     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6656     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6657
6658     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6659     for (j=0; j<2; j++) {
6660
6661         /* Inner loop just changes the D3DRS_SHADEMODE */
6662         for (i=0; i<3; i++) {
6663             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6664             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6665
6666             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6667             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6668
6669             hr = IDirect3DDevice9_BeginScene(device);
6670             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6671             if(SUCCEEDED(hr))
6672             {
6673                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6674                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6675
6676                 hr = IDirect3DDevice9_EndScene(device);
6677                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6678             }
6679
6680             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6681             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6682
6683             /* Sample two spots from the output */
6684             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6685             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6686             switch(shademode) {
6687                 case D3DSHADE_FLAT:
6688                     /* Should take the color of the first vertex of each triangle */
6689                     if (0)
6690                     {
6691                         /* This test depends on EXT_provoking_vertex being
6692                          * available. This extension is currently (20090810)
6693                          * not common enough to let the test fail if it isn't
6694                          * present. */
6695                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6696                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6697                     }
6698                     shademode = D3DSHADE_GOURAUD;
6699                     break;
6700                 case D3DSHADE_GOURAUD:
6701                     /* Should be an interpolated blend */
6702
6703                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6704                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6705                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6706                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6707
6708                     color0_gouraud = color0;
6709                     color1_gouraud = color1;
6710
6711                     shademode = D3DSHADE_PHONG;
6712                     break;
6713                 case D3DSHADE_PHONG:
6714                     /* Should be the same as GOURAUD, since no hardware implements this */
6715                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6716                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6717                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6718                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6719
6720                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6721                             color0_gouraud, color0);
6722                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6723                             color1_gouraud, color1);
6724                     break;
6725             }
6726         }
6727         /* Now, do it all over again with a TRIANGLELIST */
6728         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6729         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6730         primtype = D3DPT_TRIANGLELIST;
6731         shademode = D3DSHADE_FLAT;
6732     }
6733
6734 bail:
6735     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6736     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6737     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6738     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6739
6740     if (vb_strip)
6741         IDirect3DVertexBuffer9_Release(vb_strip);
6742     if (vb_list)
6743         IDirect3DVertexBuffer9_Release(vb_list);
6744 }
6745
6746
6747 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6748 {
6749     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6750      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6751      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6752      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6753      * 0.73
6754      *
6755      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6756      * so use shaders for this task
6757      */
6758     IDirect3DPixelShader9 *pshader;
6759     IDirect3DVertexShader9 *vshader;
6760     IDirect3D9 *d3d;
6761     DWORD vshader_code[] = {
6762         0xfffe0101,                                                             /* vs_1_1                       */
6763         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6764         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6765         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6766         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6767         0x0000ffff                                                              /* end                          */
6768     };
6769     DWORD pshader_code[] = {
6770         0xffff0101,                                                             /* ps_1_1                       */
6771         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6772         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6773         0x0000ffff                                                              /* end                          */
6774     };
6775     const float quad[] = {
6776        -1.0,   -1.0,    0.1,
6777         1.0,   -1.0,    0.1,
6778        -1.0,    1.0,    0.1,
6779         1.0,    1.0,    0.1
6780     };
6781     HRESULT hr;
6782     D3DCOLOR color;
6783
6784     IDirect3DDevice9_GetDirect3D(device, &d3d);
6785     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6786      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6787      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6788      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6789      * works
6790      */
6791     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6792                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6793                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6794         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6795         IDirect3D9_Release(d3d);
6796         return;
6797     }
6798     IDirect3D9_Release(d3d);
6799
6800     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6801     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6802
6803     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6804     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6805     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6806     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6807     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6808     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6809     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6810     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6811     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6812     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6813
6814     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6815     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6816     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6817     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6818     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6819     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6820     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6821     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6822     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6823     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6824
6825     hr = IDirect3DDevice9_BeginScene(device);
6826     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6827     if(SUCCEEDED(hr)) {
6828         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6829         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6830
6831         hr = IDirect3DDevice9_EndScene(device);
6832         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6833     }
6834
6835     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6836     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6837     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6838     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6839     IDirect3DPixelShader9_Release(pshader);
6840     IDirect3DVertexShader9_Release(vshader);
6841
6842     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6843     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6845     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6846
6847     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6848     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6849     color = getPixelColor(device, 160, 360);
6850     ok(color_match(color, 0x00808080, 1),
6851             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6852 }
6853
6854 static void alpha_test(IDirect3DDevice9 *device)
6855 {
6856     HRESULT hr;
6857     IDirect3DTexture9 *offscreenTexture;
6858     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6859     DWORD color;
6860
6861     struct vertex quad1[] =
6862     {
6863         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6864         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6865         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6866         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6867     };
6868     struct vertex quad2[] =
6869     {
6870         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6871         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6872         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6873         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6874     };
6875     static const float composite_quad[][5] = {
6876         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6877         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6878         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6879         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6880     };
6881
6882     /* Clear the render target with alpha = 0.5 */
6883     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6884     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6885
6886     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6887     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6888
6889     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6890     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6891     if(!backbuffer) {
6892         goto out;
6893     }
6894
6895     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6896     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6897     if(!offscreen) {
6898         goto out;
6899     }
6900
6901     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6902     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6903
6904     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6905     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6906     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6907     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6908     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6909     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6910     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6911     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6912     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6913     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6914
6915     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6916     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6917     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6918
6919         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6920         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6921         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6922         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6923         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6925         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6926
6927         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6928         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6929         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6930         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6931         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6932         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6933
6934         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6935          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6936          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6937         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6938         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6939         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6940         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6941
6942         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6943         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6944         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6945         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6946         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6947         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6948
6949         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6950         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6951         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6952         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6953         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6954         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6955
6956         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6957         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6958
6959         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6960          * Disable alpha blending for the final composition
6961          */
6962         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6963         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6964         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6965         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6966
6967         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6968         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6970         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6971         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6972         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6973
6974         hr = IDirect3DDevice9_EndScene(device);
6975         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6976     }
6977
6978     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6979
6980     color = getPixelColor(device, 160, 360);
6981     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6982        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6983
6984     color = getPixelColor(device, 160, 120);
6985     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6986        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6987
6988     color = getPixelColor(device, 480, 360);
6989     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6990        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6991
6992     color = getPixelColor(device, 480, 120);
6993     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6994        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6995
6996     out:
6997     /* restore things */
6998     if(backbuffer) {
6999         IDirect3DSurface9_Release(backbuffer);
7000     }
7001     if(offscreenTexture) {
7002         IDirect3DTexture9_Release(offscreenTexture);
7003     }
7004     if(offscreen) {
7005         IDirect3DSurface9_Release(offscreen);
7006     }
7007 }
7008
7009 struct vertex_shortcolor {
7010     float x, y, z;
7011     unsigned short r, g, b, a;
7012 };
7013 struct vertex_floatcolor {
7014     float x, y, z;
7015     float r, g, b, a;
7016 };
7017
7018 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7019 {
7020     HRESULT hr;
7021     BOOL s_ok, ub_ok, f_ok;
7022     DWORD color, size, i;
7023     void *data;
7024     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7025         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7026         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7027         D3DDECL_END()
7028     };
7029     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7030         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7031         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7032         D3DDECL_END()
7033     };
7034     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7035         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7036         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7037         D3DDECL_END()
7038     };
7039     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7040         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7041         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7042         D3DDECL_END()
7043     };
7044     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7045         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7046         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7047         D3DDECL_END()
7048     };
7049     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7050         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7051         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7052         D3DDECL_END()
7053     };
7054     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7055         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7056         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7057         D3DDECL_END()
7058     };
7059     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7060     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7061     IDirect3DVertexBuffer9 *vb, *vb2;
7062     struct vertex quad1[] =                             /* D3DCOLOR */
7063     {
7064         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7065         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7066         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7067         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7068     };
7069     struct vertex quad2[] =                             /* UBYTE4N */
7070     {
7071         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7072         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7073         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7074         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7075     };
7076     struct vertex_shortcolor quad3[] =                  /* short */
7077     {
7078         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7079         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7080         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7081         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7082     };
7083     struct vertex_floatcolor quad4[] =
7084     {
7085         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7086         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7087         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7088         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7089     };
7090     DWORD colors[] = {
7091         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7092         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7093         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7094         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7095         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7096         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7097         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7098         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7099         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7100         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7101         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7102         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7103         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7104         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7105         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7106         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7107     };
7108     float quads[] = {
7109         -1.0,   -1.0,     0.1,
7110         -1.0,    0.0,     0.1,
7111          0.0,   -1.0,     0.1,
7112          0.0,    0.0,     0.1,
7113
7114          0.0,   -1.0,     0.1,
7115          0.0,    0.0,     0.1,
7116          1.0,   -1.0,     0.1,
7117          1.0,    0.0,     0.1,
7118
7119          0.0,    0.0,     0.1,
7120          0.0,    1.0,     0.1,
7121          1.0,    0.0,     0.1,
7122          1.0,    1.0,     0.1,
7123
7124         -1.0,    0.0,     0.1,
7125         -1.0,    1.0,     0.1,
7126          0.0,    0.0,     0.1,
7127          0.0,    1.0,     0.1
7128     };
7129     struct tvertex quad_transformed[] = {
7130        {  90,    110,     0.1,      2.0,        0x00ffff00},
7131        { 570,    110,     0.1,      2.0,        0x00ffff00},
7132        {  90,    300,     0.1,      2.0,        0x00ffff00},
7133        { 570,    300,     0.1,      2.0,        0x00ffff00}
7134     };
7135     D3DCAPS9 caps;
7136
7137     memset(&caps, 0, sizeof(caps));
7138     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7139     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7140
7141     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7142     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7143
7144     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7145     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7146     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7147     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7148     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7149     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7150     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7151         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7152         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7153         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7154         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7155     } else {
7156         trace("D3DDTCAPS_UBYTE4N not supported\n");
7157         dcl_ubyte_2 = NULL;
7158         dcl_ubyte = NULL;
7159     }
7160     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7161     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7162     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7163     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7164
7165     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7166     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7167                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7168     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7169
7170     hr = IDirect3DDevice9_BeginScene(device);
7171     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7172     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7173     if(SUCCEEDED(hr)) {
7174         if(dcl_color) {
7175             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7176             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7177             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7178             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7179         }
7180
7181         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7182          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7183          * using software vertex processing. Doh!
7184          */
7185         if(dcl_ubyte) {
7186             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7187             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7188             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7189             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7190             ub_ok = SUCCEEDED(hr);
7191         }
7192
7193         if(dcl_short) {
7194             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7195             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7196             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7197             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7198             s_ok = SUCCEEDED(hr);
7199         }
7200
7201         if(dcl_float) {
7202             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7203             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7204             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7205             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7206             f_ok = SUCCEEDED(hr);
7207         }
7208
7209         hr = IDirect3DDevice9_EndScene(device);
7210         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7211     }
7212
7213     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7214     if(dcl_short) {
7215         color = getPixelColor(device, 480, 360);
7216         ok(color == 0x000000ff || !s_ok,
7217            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7218     }
7219     if(dcl_ubyte) {
7220         color = getPixelColor(device, 160, 120);
7221         ok(color == 0x0000ffff || !ub_ok,
7222            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7223     }
7224     if(dcl_color) {
7225         color = getPixelColor(device, 160, 360);
7226         ok(color == 0x00ffff00,
7227            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7228     }
7229     if(dcl_float) {
7230         color = getPixelColor(device, 480, 120);
7231         ok(color == 0x00ff0000 || !f_ok,
7232            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7233     }
7234
7235     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7236      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7237      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7238      * whether the immediate mode code works
7239      */
7240     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7241     hr = IDirect3DDevice9_BeginScene(device);
7242     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7243     if(SUCCEEDED(hr)) {
7244         if(dcl_color) {
7245             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7246             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7247             memcpy(data, quad1, sizeof(quad1));
7248             hr = IDirect3DVertexBuffer9_Unlock(vb);
7249             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7250             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7251             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7252             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7253             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7254             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7255             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7256         }
7257
7258         if(dcl_ubyte) {
7259             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7260             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7261             memcpy(data, quad2, sizeof(quad2));
7262             hr = IDirect3DVertexBuffer9_Unlock(vb);
7263             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7264             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7265             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7266             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7267             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7268             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7269             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7270                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7271             ub_ok = SUCCEEDED(hr);
7272         }
7273
7274         if(dcl_short) {
7275             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7276             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7277             memcpy(data, quad3, sizeof(quad3));
7278             hr = IDirect3DVertexBuffer9_Unlock(vb);
7279             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7280             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7281             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7282             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7283             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7284             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7285             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7286                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7287             s_ok = SUCCEEDED(hr);
7288         }
7289
7290         if(dcl_float) {
7291             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7292             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7293             memcpy(data, quad4, sizeof(quad4));
7294             hr = IDirect3DVertexBuffer9_Unlock(vb);
7295             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7296             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7297             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7298             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7299             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7300             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7301             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7302                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7303             f_ok = SUCCEEDED(hr);
7304         }
7305
7306         hr = IDirect3DDevice9_EndScene(device);
7307         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7308     }
7309
7310     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7311     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7312     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7313     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7314
7315     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7316     if(dcl_short) {
7317         color = getPixelColor(device, 480, 360);
7318         ok(color == 0x000000ff || !s_ok,
7319            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7320     }
7321     if(dcl_ubyte) {
7322         color = getPixelColor(device, 160, 120);
7323         ok(color == 0x0000ffff || !ub_ok,
7324            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7325     }
7326     if(dcl_color) {
7327         color = getPixelColor(device, 160, 360);
7328         ok(color == 0x00ffff00,
7329            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7330     }
7331     if(dcl_float) {
7332         color = getPixelColor(device, 480, 120);
7333         ok(color == 0x00ff0000 || !f_ok,
7334            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7335     }
7336
7337     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7338     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7339
7340     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7341     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7342     memcpy(data, quad_transformed, sizeof(quad_transformed));
7343     hr = IDirect3DVertexBuffer9_Unlock(vb);
7344     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7345
7346     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7347     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7348
7349     hr = IDirect3DDevice9_BeginScene(device);
7350     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7351     if(SUCCEEDED(hr)) {
7352         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7353         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7354         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7355         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7356
7357         hr = IDirect3DDevice9_EndScene(device);
7358         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7359     }
7360
7361     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7362     color = getPixelColor(device, 88, 108);
7363     ok(color == 0x000000ff,
7364        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7365     color = getPixelColor(device, 92, 108);
7366     ok(color == 0x000000ff,
7367        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7368     color = getPixelColor(device, 88, 112);
7369     ok(color == 0x000000ff,
7370        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7371     color = getPixelColor(device, 92, 112);
7372     ok(color == 0x00ffff00,
7373        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7374
7375     color = getPixelColor(device, 568, 108);
7376     ok(color == 0x000000ff,
7377        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7378     color = getPixelColor(device, 572, 108);
7379     ok(color == 0x000000ff,
7380        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7381     color = getPixelColor(device, 568, 112);
7382     ok(color == 0x00ffff00,
7383        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7384     color = getPixelColor(device, 572, 112);
7385     ok(color == 0x000000ff,
7386        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7387
7388     color = getPixelColor(device, 88, 298);
7389     ok(color == 0x000000ff,
7390        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7391     color = getPixelColor(device, 92, 298);
7392     ok(color == 0x00ffff00,
7393        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7394     color = getPixelColor(device, 88, 302);
7395     ok(color == 0x000000ff,
7396        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7397     color = getPixelColor(device, 92, 302);
7398     ok(color == 0x000000ff,
7399        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7400
7401     color = getPixelColor(device, 568, 298);
7402     ok(color == 0x00ffff00,
7403        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7404     color = getPixelColor(device, 572, 298);
7405     ok(color == 0x000000ff,
7406        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7407     color = getPixelColor(device, 568, 302);
7408     ok(color == 0x000000ff,
7409        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7410     color = getPixelColor(device, 572, 302);
7411     ok(color == 0x000000ff,
7412        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7413
7414     /* This test is pointless without those two declarations: */
7415     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7416         skip("color-ubyte switching test declarations aren't supported\n");
7417         goto out;
7418     }
7419
7420     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7421     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7422     memcpy(data, quads, sizeof(quads));
7423     hr = IDirect3DVertexBuffer9_Unlock(vb);
7424     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7425     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7426                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7427     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7428     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7429     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7430     memcpy(data, colors, sizeof(colors));
7431     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7432     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7433
7434     for(i = 0; i < 2; i++) {
7435         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7436         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7437
7438         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7439         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7440         if(i == 0) {
7441             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7442         } else {
7443             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7444         }
7445         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7446
7447         hr = IDirect3DDevice9_BeginScene(device);
7448         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7449         ub_ok = FALSE;
7450         if(SUCCEEDED(hr)) {
7451             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7452             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7453             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7454             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7455                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7456             ub_ok = SUCCEEDED(hr);
7457
7458             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7459             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7460             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7461             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7462
7463             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7464             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7465             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7466             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7467                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7468             ub_ok = (SUCCEEDED(hr) && ub_ok);
7469
7470             hr = IDirect3DDevice9_EndScene(device);
7471             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7472         }
7473
7474         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7475         if(i == 0) {
7476             color = getPixelColor(device, 480, 360);
7477             ok(color == 0x00ff0000,
7478                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7479             color = getPixelColor(device, 160, 120);
7480             ok(color == 0x00ffffff,
7481                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7482             color = getPixelColor(device, 160, 360);
7483             ok(color == 0x000000ff || !ub_ok,
7484                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7485             color = getPixelColor(device, 480, 120);
7486             ok(color == 0x000000ff || !ub_ok,
7487                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7488         } else {
7489             color = getPixelColor(device, 480, 360);
7490             ok(color == 0x000000ff,
7491                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7492             color = getPixelColor(device, 160, 120);
7493             ok(color == 0x00ffffff,
7494                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7495             color = getPixelColor(device, 160, 360);
7496             ok(color == 0x00ff0000 || !ub_ok,
7497                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7498             color = getPixelColor(device, 480, 120);
7499             ok(color == 0x00ff0000 || !ub_ok,
7500                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7501         }
7502     }
7503
7504     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7505     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7506     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7507     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7508     IDirect3DVertexBuffer9_Release(vb2);
7509
7510     out:
7511     IDirect3DVertexBuffer9_Release(vb);
7512     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7513     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7514     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7515     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7516     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7517     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7518     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7519 }
7520
7521 struct vertex_float16color {
7522     float x, y, z;
7523     DWORD c1, c2;
7524 };
7525
7526 static void test_vshader_float16(IDirect3DDevice9 *device)
7527 {
7528     HRESULT hr;
7529     DWORD color;
7530     void *data;
7531     static const D3DVERTEXELEMENT9 decl_elements[] = {
7532         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7533         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7534         D3DDECL_END()
7535     };
7536     IDirect3DVertexDeclaration9 *vdecl = NULL;
7537     IDirect3DVertexBuffer9 *buffer = NULL;
7538     IDirect3DVertexShader9 *shader;
7539     DWORD shader_code[] = {
7540         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7541         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7542         0x90e40001, 0x0000ffff
7543     };
7544     struct vertex_float16color quad[] = {
7545         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7546         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7547         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7548         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7549
7550         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7551         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7552         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7553         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7554
7555         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7556         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7557         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7558         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7559
7560         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7561         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7562         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7563         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7564     };
7565
7566     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7567     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7568
7569     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7570     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7571     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7572     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7573     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7574     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7575
7576     hr = IDirect3DDevice9_BeginScene(device);
7577     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7578     if(SUCCEEDED(hr)) {
7579         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7580         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7581         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7582         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7583         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7584         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7585         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7586         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7587         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7588         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7589
7590         hr = IDirect3DDevice9_EndScene(device);
7591         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7592     }
7593     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7594     color = getPixelColor(device, 480, 360);
7595     ok(color == 0x00ff0000,
7596        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7597     color = getPixelColor(device, 160, 120);
7598     ok(color == 0x00000000,
7599        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7600     color = getPixelColor(device, 160, 360);
7601     ok(color == 0x0000ff00,
7602        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7603     color = getPixelColor(device, 480, 120);
7604     ok(color == 0x000000ff,
7605        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7606
7607     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7608     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7609
7610     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7611                                              D3DPOOL_MANAGED, &buffer, NULL);
7612     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7613     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7614     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7615     memcpy(data, quad, sizeof(quad));
7616     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7617     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7618     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7619     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7620
7621     hr = IDirect3DDevice9_BeginScene(device);
7622     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7623     if(SUCCEEDED(hr)) {
7624             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7625             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7626             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7627             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7628             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7629             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7630             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7631             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7632
7633             hr = IDirect3DDevice9_EndScene(device);
7634             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7635     }
7636
7637     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7638     color = getPixelColor(device, 480, 360);
7639     ok(color == 0x00ff0000,
7640        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7641     color = getPixelColor(device, 160, 120);
7642     ok(color == 0x00000000,
7643        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7644     color = getPixelColor(device, 160, 360);
7645     ok(color == 0x0000ff00,
7646        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7647     color = getPixelColor(device, 480, 120);
7648     ok(color == 0x000000ff,
7649        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7650
7651     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7652     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7653     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7654     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7655     IDirect3DDevice9_SetVertexShader(device, NULL);
7656     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7657
7658     IDirect3DVertexDeclaration9_Release(vdecl);
7659     IDirect3DVertexShader9_Release(shader);
7660     IDirect3DVertexBuffer9_Release(buffer);
7661 }
7662
7663 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7664 {
7665     D3DCAPS9 caps;
7666     IDirect3DTexture9 *texture;
7667     HRESULT hr;
7668     D3DLOCKED_RECT rect;
7669     unsigned int x, y;
7670     DWORD *dst, color;
7671     const float quad[] = {
7672         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7673          1.0,   -1.0,   0.1,    1.2,   -0.2,
7674         -1.0,    1.0,   0.1,   -0.2,    1.2,
7675          1.0,    1.0,   0.1,    1.2,    1.2
7676     };
7677     memset(&caps, 0, sizeof(caps));
7678
7679     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7680     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7681     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7682         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7683         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7684            "Card has conditional NP2 support without power of two restriction set\n");
7685         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7686         return;
7687     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7688         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7689         return;
7690     }
7691
7692     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7693     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7694
7695     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7696     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7697
7698     memset(&rect, 0, sizeof(rect));
7699     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7700     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7701     for(y = 0; y < 10; y++) {
7702         for(x = 0; x < 10; x++) {
7703             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7704             if(x == 0 || x == 9 || y == 0 || y == 9) {
7705                 *dst = 0x00ff0000;
7706             } else {
7707                 *dst = 0x000000ff;
7708             }
7709         }
7710     }
7711     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7712     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7713
7714     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7715     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7716     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7717     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7718     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7719     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7720     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7721     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7722
7723     hr = IDirect3DDevice9_BeginScene(device);
7724     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7725     if(SUCCEEDED(hr)) {
7726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7727         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7728
7729         hr = IDirect3DDevice9_EndScene(device);
7730         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7731     }
7732
7733     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7734
7735     color = getPixelColor(device,    1,  1);
7736     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7737     color = getPixelColor(device, 639, 479);
7738     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7739
7740     color = getPixelColor(device, 135, 101);
7741     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7742     color = getPixelColor(device, 140, 101);
7743     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7744     color = getPixelColor(device, 135, 105);
7745     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7746     color = getPixelColor(device, 140, 105);
7747     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7748
7749     color = getPixelColor(device, 135, 376);
7750     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7751     color = getPixelColor(device, 140, 376);
7752     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7753     color = getPixelColor(device, 135, 379);
7754     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7755     color = getPixelColor(device, 140, 379);
7756     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7757
7758     color = getPixelColor(device, 500, 101);
7759     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7760     color = getPixelColor(device, 504, 101);
7761     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7762     color = getPixelColor(device, 500, 105);
7763     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7764     color = getPixelColor(device, 504, 105);
7765     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7766
7767     color = getPixelColor(device, 500, 376);
7768     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7769     color = getPixelColor(device, 504, 376);
7770     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7771     color = getPixelColor(device, 500, 380);
7772     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7773     color = getPixelColor(device, 504, 380);
7774     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7775
7776     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7777     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7778     IDirect3DTexture9_Release(texture);
7779 }
7780
7781 static void vFace_register_test(IDirect3DDevice9 *device)
7782 {
7783     HRESULT hr;
7784     DWORD color;
7785     const DWORD shader_code[] = {
7786         0xffff0300,                                                             /* ps_3_0                     */
7787         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7788         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7789         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7790         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7791         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7792         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7793         0x0000ffff                                                              /* END                        */
7794     };
7795     IDirect3DPixelShader9 *shader;
7796     IDirect3DTexture9 *texture;
7797     IDirect3DSurface9 *surface, *backbuffer;
7798     const float quad[] = {
7799         -1.0,   -1.0,   0.1,
7800          1.0,   -1.0,   0.1,
7801         -1.0,    0.0,   0.1,
7802
7803          1.0,   -1.0,   0.1,
7804          1.0,    0.0,   0.1,
7805         -1.0,    0.0,   0.1,
7806
7807         -1.0,    0.0,   0.1,
7808         -1.0,    1.0,   0.1,
7809          1.0,    0.0,   0.1,
7810
7811          1.0,    0.0,   0.1,
7812         -1.0,    1.0,   0.1,
7813          1.0,    1.0,   0.1,
7814     };
7815     const float blit[] = {
7816          0.0,   -1.0,   0.1,    0.0,    0.0,
7817          1.0,   -1.0,   0.1,    1.0,    0.0,
7818          0.0,    1.0,   0.1,    0.0,    1.0,
7819          1.0,    1.0,   0.1,    1.0,    1.0,
7820     };
7821
7822     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7823     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7824     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7825     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7826     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7827     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7828     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7829     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7830     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7831     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7832     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7833     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7834
7835     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7836     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7837
7838     hr = IDirect3DDevice9_BeginScene(device);
7839     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7840     if(SUCCEEDED(hr)) {
7841         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7842         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7843         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7844         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7845         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7846         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7847         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7848         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7849         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7850         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7851         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7852
7853         /* Blit the texture onto the back buffer to make it visible */
7854         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7855         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7856         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7857         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7858         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7859         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7860         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7861         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7862         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7863         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7864
7865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7866         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7867
7868         hr = IDirect3DDevice9_EndScene(device);
7869         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7870     }
7871
7872     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7873     color = getPixelColor(device, 160, 360);
7874     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7875     color = getPixelColor(device, 160, 120);
7876     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7877     color = getPixelColor(device, 480, 360);
7878     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7879     color = getPixelColor(device, 480, 120);
7880     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7881
7882     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7883     IDirect3DDevice9_SetTexture(device, 0, NULL);
7884     IDirect3DPixelShader9_Release(shader);
7885     IDirect3DSurface9_Release(surface);
7886     IDirect3DSurface9_Release(backbuffer);
7887     IDirect3DTexture9_Release(texture);
7888 }
7889
7890 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7891 {
7892     HRESULT hr;
7893     DWORD color;
7894     int i;
7895     D3DCAPS9 caps;
7896     BOOL L6V5U5_supported = FALSE;
7897     IDirect3DTexture9 *tex1, *tex2;
7898     D3DLOCKED_RECT locked_rect;
7899
7900     static const float quad[][7] = {
7901         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7902         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7903         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7904         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7905     };
7906
7907     static const D3DVERTEXELEMENT9 decl_elements[] = {
7908         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7909         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7910         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7911         D3DDECL_END()
7912     };
7913
7914     /* use asymmetric matrix to test loading */
7915     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7916     float scale, offset;
7917
7918     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7919     IDirect3DTexture9           *texture            = NULL;
7920
7921     memset(&caps, 0, sizeof(caps));
7922     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7923     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7924     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7925         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7926         return;
7927     } else {
7928         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7929          * They report that it is not supported, but after that bump mapping works properly. So just test
7930          * if the format is generally supported, and check the BUMPENVMAP flag
7931          */
7932         IDirect3D9 *d3d9;
7933
7934         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7935         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7936                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7937         L6V5U5_supported = SUCCEEDED(hr);
7938         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7939                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7940         IDirect3D9_Release(d3d9);
7941         if(FAILED(hr)) {
7942             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7943             return;
7944         }
7945     }
7946
7947     /* Generate the textures */
7948     generate_bumpmap_textures(device);
7949
7950     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7951     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7952     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7953     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7954     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7955     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7956     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7957     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7958
7959     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7960     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7961     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7962     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7963     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7964     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7965
7966     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7967     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7968     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7969     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7970     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7971     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7972
7973     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7974     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7975
7976     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7977     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7978
7979     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7980     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7981
7982
7983     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7984     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7985     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7986     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7987
7988     hr = IDirect3DDevice9_BeginScene(device);
7989     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7990
7991     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7992     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7993
7994     hr = IDirect3DDevice9_EndScene(device);
7995     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7996
7997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7998     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7999
8000     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8001      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8002      * But since testing the color match is not the purpose of the test don't be too picky
8003      */
8004     color = getPixelColor(device, 320-32, 240);
8005     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8006     color = getPixelColor(device, 320+32, 240);
8007     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8008     color = getPixelColor(device, 320, 240-32);
8009     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8010     color = getPixelColor(device, 320, 240+32);
8011     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8012     color = getPixelColor(device, 320, 240);
8013     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8014     color = getPixelColor(device, 320+32, 240+32);
8015     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8016     color = getPixelColor(device, 320-32, 240+32);
8017     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8018     color = getPixelColor(device, 320+32, 240-32);
8019     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8020     color = getPixelColor(device, 320-32, 240-32);
8021     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8022
8023     for(i = 0; i < 2; i++) {
8024         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8025         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8026         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8027         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8028         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8029         IDirect3DTexture9_Release(texture); /* To destroy it */
8030     }
8031
8032     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8033         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8034         goto cleanup;
8035     }
8036     if(L6V5U5_supported == FALSE) {
8037         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8038         goto cleanup;
8039     }
8040
8041     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8042     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8043     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8044      * would only make this test more complicated
8045      */
8046     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8047     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8048     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8049     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8050
8051     memset(&locked_rect, 0, sizeof(locked_rect));
8052     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8053     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8054     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8055     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8056     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8057
8058     memset(&locked_rect, 0, sizeof(locked_rect));
8059     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8060     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8061     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8062     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8063     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8064
8065     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8066     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8067     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8068     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8069
8070     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8071     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8072     scale = 2.0;
8073     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8074     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8075     offset = 0.1;
8076     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8077     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8078
8079     hr = IDirect3DDevice9_BeginScene(device);
8080     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8081     if(SUCCEEDED(hr)) {
8082         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8083         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8084         hr = IDirect3DDevice9_EndScene(device);
8085         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8086     }
8087
8088     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8089     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8090     color = getPixelColor(device, 320, 240);
8091     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8092      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8093      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8094      */
8095     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8096
8097     /* Check a result scale factor > 1.0 */
8098     scale = 10;
8099     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8100     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8101     offset = 10;
8102     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8103     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8104
8105     hr = IDirect3DDevice9_BeginScene(device);
8106     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8107     if(SUCCEEDED(hr)) {
8108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8109         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8110         hr = IDirect3DDevice9_EndScene(device);
8111         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8112     }
8113     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8114     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8115     color = getPixelColor(device, 320, 240);
8116     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8117
8118     /* Check clamping in the scale factor calculation */
8119     scale = 1000;
8120     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8121     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8122     offset = -1;
8123     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8124     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8125
8126     hr = IDirect3DDevice9_BeginScene(device);
8127     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8128     if(SUCCEEDED(hr)) {
8129         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8130         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8131         hr = IDirect3DDevice9_EndScene(device);
8132         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8133     }
8134     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8135     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8136     color = getPixelColor(device, 320, 240);
8137     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8138
8139     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8140     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8141     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8142     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8143
8144     IDirect3DTexture9_Release(tex1);
8145     IDirect3DTexture9_Release(tex2);
8146
8147 cleanup:
8148     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8149     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8150     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8151     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8152
8153     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8154     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8155     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8156 }
8157
8158 static void stencil_cull_test(IDirect3DDevice9 *device) {
8159     HRESULT hr;
8160     IDirect3DSurface9 *depthstencil = NULL;
8161     D3DSURFACE_DESC desc;
8162     float quad1[] = {
8163         -1.0,   -1.0,   0.1,
8164          0.0,   -1.0,   0.1,
8165         -1.0,    0.0,   0.1,
8166          0.0,    0.0,   0.1,
8167     };
8168     float quad2[] = {
8169          0.0,   -1.0,   0.1,
8170          1.0,   -1.0,   0.1,
8171          0.0,    0.0,   0.1,
8172          1.0,    0.0,   0.1,
8173     };
8174     float quad3[] = {
8175         0.0,    0.0,   0.1,
8176         1.0,    0.0,   0.1,
8177         0.0,    1.0,   0.1,
8178         1.0,    1.0,   0.1,
8179     };
8180     float quad4[] = {
8181         -1.0,    0.0,   0.1,
8182          0.0,    0.0,   0.1,
8183         -1.0,    1.0,   0.1,
8184          0.0,    1.0,   0.1,
8185     };
8186     struct vertex painter[] = {
8187        {-1.0,   -1.0,   0.0,    0x00000000},
8188        { 1.0,   -1.0,   0.0,    0x00000000},
8189        {-1.0,    1.0,   0.0,    0x00000000},
8190        { 1.0,    1.0,   0.0,    0x00000000},
8191     };
8192     WORD indices_cw[]  = {0, 1, 3};
8193     WORD indices_ccw[] = {0, 2, 3};
8194     unsigned int i;
8195     DWORD color;
8196
8197     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8198     if(depthstencil == NULL) {
8199         skip("No depth stencil buffer\n");
8200         return;
8201     }
8202     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8203     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8204     IDirect3DSurface9_Release(depthstencil);
8205     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8206         skip("No 4 or 8 bit stencil surface\n");
8207         return;
8208     }
8209
8210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8211     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8212     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8213
8214     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8215     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8216     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8217     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8218     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8219     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8220     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8221     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8222
8223     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8224     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8225     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8226     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8227     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8228     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8229
8230     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8231     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8232     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8233     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8234
8235     /* First pass: Fill the stencil buffer with some values... */
8236     hr = IDirect3DDevice9_BeginScene(device);
8237     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8238     if(SUCCEEDED(hr))
8239     {
8240         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8241         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8242         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8243                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8244         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8245         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8246                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8247         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8248
8249         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8250         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8251         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8252         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8253         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8254                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8255         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8256         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8257                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8258         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8259
8260         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8261         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8263                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8264         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8265         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8266                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8267         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8268
8269         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8270         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8271         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8272                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8273         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8274         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8275                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8276         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8277
8278         hr = IDirect3DDevice9_EndScene(device);
8279         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8280     }
8281
8282     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8283     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8284     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8285     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8286     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8287     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8288     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8294     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8295
8296     /* 2nd pass: Make the stencil values visible */
8297     hr = IDirect3DDevice9_BeginScene(device);
8298     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8299     if(SUCCEEDED(hr))
8300     {
8301         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8302         for(i = 0; i < 16; i++) {
8303             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8304             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8305
8306             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8307             painter[1].diffuse = (i * 16);
8308             painter[2].diffuse = (i * 16);
8309             painter[3].diffuse = (i * 16);
8310             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8311             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8312         }
8313         hr = IDirect3DDevice9_EndScene(device);
8314         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8315     }
8316
8317     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8318     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8319
8320     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8322
8323     color = getPixelColor(device, 160, 420);
8324     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8325     color = getPixelColor(device, 160, 300);
8326     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8327
8328     color = getPixelColor(device, 480, 420);
8329     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8330     color = getPixelColor(device, 480, 300);
8331     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8332
8333     color = getPixelColor(device, 160, 180);
8334     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8335     color = getPixelColor(device, 160, 60);
8336     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8337
8338     color = getPixelColor(device, 480, 180);
8339     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8340     color = getPixelColor(device, 480, 60);
8341     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8342 }
8343
8344 static void vpos_register_test(IDirect3DDevice9 *device)
8345 {
8346     HRESULT hr;
8347     DWORD color;
8348     const DWORD shader_code[] = {
8349     0xffff0300,                                                             /* ps_3_0                     */
8350     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8351     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8352     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8353     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8354     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8355     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8356     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8357     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8358     0x0000ffff                                                              /* end                        */
8359     };
8360     const DWORD shader_frac_code[] = {
8361     0xffff0300,                                                             /* ps_3_0                     */
8362     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8363     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8364     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8365     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8366     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8367     0x0000ffff                                                              /* end                        */
8368     };
8369     IDirect3DPixelShader9 *shader, *shader_frac;
8370     IDirect3DSurface9 *surface = NULL, *backbuffer;
8371     const float quad[] = {
8372         -1.0,   -1.0,   0.1,    0.0,    0.0,
8373          1.0,   -1.0,   0.1,    1.0,    0.0,
8374         -1.0,    1.0,   0.1,    0.0,    1.0,
8375          1.0,    1.0,   0.1,    1.0,    1.0,
8376     };
8377     D3DLOCKED_RECT lr;
8378     float constant[4] = {1.0, 0.0, 320, 240};
8379     DWORD *pos;
8380
8381     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8382     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8383     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8384     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8385     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8386     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8387     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8388     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8389     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8390     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8391     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8392     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8393
8394     hr = IDirect3DDevice9_BeginScene(device);
8395     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8396     if(SUCCEEDED(hr)) {
8397         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8398         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8399         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8400         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8401         hr = IDirect3DDevice9_EndScene(device);
8402         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8403     }
8404
8405     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8406     /* This has to be pixel exact */
8407     color = getPixelColor(device, 319, 239);
8408     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8409     color = getPixelColor(device, 320, 239);
8410     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8411     color = getPixelColor(device, 319, 240);
8412     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8413     color = getPixelColor(device, 320, 240);
8414     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8415
8416     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8417                                              &surface, NULL);
8418     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8419     hr = IDirect3DDevice9_BeginScene(device);
8420     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8421     if(SUCCEEDED(hr)) {
8422         constant[2] = 16; constant[3] = 16;
8423         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8424         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8425         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8426         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8427         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8428         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8429         hr = IDirect3DDevice9_EndScene(device);
8430         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8431     }
8432     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8433     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8434
8435     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8436     color = *pos & 0x00ffffff;
8437     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8438     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8439     color = *pos & 0x00ffffff;
8440     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8441     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8442     color = *pos & 0x00ffffff;
8443     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8444     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8445     color = *pos & 0x00ffffff;
8446     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8447
8448     hr = IDirect3DSurface9_UnlockRect(surface);
8449     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8450
8451     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8452      * have full control over the multisampling setting inside this test
8453      */
8454     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8455     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8456     hr = IDirect3DDevice9_BeginScene(device);
8457     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8458     if(SUCCEEDED(hr)) {
8459         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8460         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8461         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8462         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8463         hr = IDirect3DDevice9_EndScene(device);
8464         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8465     }
8466     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8467     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8468
8469     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8470     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8471
8472     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8473     color = *pos & 0x00ffffff;
8474     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8475
8476     hr = IDirect3DSurface9_UnlockRect(surface);
8477     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8478
8479     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8480     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8481     IDirect3DPixelShader9_Release(shader);
8482     IDirect3DPixelShader9_Release(shader_frac);
8483     if(surface) IDirect3DSurface9_Release(surface);
8484     IDirect3DSurface9_Release(backbuffer);
8485 }
8486
8487 static void pointsize_test(IDirect3DDevice9 *device)
8488 {
8489     HRESULT hr;
8490     D3DCAPS9 caps;
8491     D3DMATRIX matrix;
8492     D3DMATRIX identity;
8493     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8494     DWORD color;
8495     IDirect3DTexture9 *tex1, *tex2;
8496     D3DLOCKED_RECT lr;
8497     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8498                                 0x00000000, 0x00000000};
8499     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8500                                 0x00000000, 0x0000ff00};
8501
8502     const float vertices[] = {
8503         64,     64,     0.1,
8504         128,    64,     0.1,
8505         192,    64,     0.1,
8506         256,    64,     0.1,
8507         320,    64,     0.1,
8508         384,    64,     0.1,
8509         448,    64,     0.1,
8510         512,    64,     0.1,
8511         576,    64,     0.1,
8512     };
8513
8514     /* 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 */
8515     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;
8516     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;
8517     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;
8518     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;
8519
8520     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;
8521     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;
8522     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;
8523     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;
8524
8525     memset(&caps, 0, sizeof(caps));
8526     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8527     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8528     if(caps.MaxPointSize < 32.0) {
8529         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8530         return;
8531     }
8532
8533     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8534     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8535     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8536     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8537     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8538     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8539     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8540     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8541
8542     hr = IDirect3DDevice9_BeginScene(device);
8543     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8544     if(SUCCEEDED(hr)) {
8545         ptsize = 16.0;
8546         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8547         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8548         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8549         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8550
8551         ptsize = 32.0;
8552         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8553         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8554         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8555         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8556
8557         ptsize = 31.5;
8558         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8559         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8560         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8561         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8562
8563         if(caps.MaxPointSize >= 64.0) {
8564             ptsize = 64.0;
8565             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8566             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8567             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8568             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8569
8570             ptsize = 63.75;
8571             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8572             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8573             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8574             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8575         }
8576
8577         ptsize = 1.0;
8578         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8579         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8580         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8581         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8582
8583         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8584         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8585         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8586         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8587
8588         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8589         ptsize = 16.0;
8590         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8591         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8592         ptsize = 1.0;
8593         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8594         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8595         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8596         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8597
8598         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8599          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8600          */
8601         ptsize = 4.0;
8602         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8603         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8604         ptsize = 16.0;
8605         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8606         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8607         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8608         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8609
8610         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8611         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8612
8613         /* pointsize < pointsize_min < pointsize_max?
8614          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8615          */
8616         ptsize = 1.0;
8617         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8618         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8619         ptsize = 16.0;
8620         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8621         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8622         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8623         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8624
8625         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8626         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8627
8628         hr = IDirect3DDevice9_EndScene(device);
8629         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8630     }
8631     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8632     color = getPixelColor(device, 64-9, 64-9);
8633     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8634     color = getPixelColor(device, 64-8, 64-8);
8635     ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8636     color = getPixelColor(device, 64-7, 64-7);
8637     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8638     color = getPixelColor(device, 64+7, 64+7);
8639     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8640     color = getPixelColor(device, 64+8, 64+8);
8641     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8642     color = getPixelColor(device, 64+9, 64+9);
8643     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8644
8645     color = getPixelColor(device, 128-17, 64-17);
8646     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8647     color = getPixelColor(device, 128-16, 64-16);
8648     ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8649     color = getPixelColor(device, 128-15, 64-15);
8650     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8651     color = getPixelColor(device, 128+15, 64+15);
8652     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8653     color = getPixelColor(device, 128+16, 64+16);
8654     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8655     color = getPixelColor(device, 128+17, 64+17);
8656     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8657
8658     color = getPixelColor(device, 192-17, 64-17);
8659     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8660     color = getPixelColor(device, 192-16, 64-16);
8661     todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8662     color = getPixelColor(device, 192-15, 64-15);
8663     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8664     color = getPixelColor(device, 192+15, 64+15);
8665     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8666     color = getPixelColor(device, 192+16, 64+16);
8667     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8668     color = getPixelColor(device, 192+17, 64+17);
8669     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8670
8671     if(caps.MaxPointSize >= 64.0) {
8672         color = getPixelColor(device, 256-33, 64-33);
8673         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8674         color = getPixelColor(device, 256-32, 64-32);
8675         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8676         color = getPixelColor(device, 256-31, 64-31);
8677         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8678         color = getPixelColor(device, 256+31, 64+31);
8679         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8680         color = getPixelColor(device, 256+32, 64+32);
8681         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8682         color = getPixelColor(device, 256+33, 64+33);
8683         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8684
8685         color = getPixelColor(device, 384-33, 64-33);
8686         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8687         color = getPixelColor(device, 384-32, 64-32);
8688         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8689         color = getPixelColor(device, 384-31, 64-31);
8690         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8691         color = getPixelColor(device, 384+31, 64+31);
8692         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8693         color = getPixelColor(device, 384+32, 64+32);
8694         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8695         color = getPixelColor(device, 384+33, 64+33);
8696         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8697     }
8698
8699     color = getPixelColor(device, 320-1, 64-1);
8700     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8701     color = getPixelColor(device, 320-0, 64-0);
8702     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8703     color = getPixelColor(device, 320+1, 64+1);
8704     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8705
8706     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8707     color = getPixelColor(device, 448-4, 64-4);
8708     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8709     color = getPixelColor(device, 448+4, 64+4);
8710     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8711
8712     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8713     color = getPixelColor(device, 512-4, 64-4);
8714     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8715     color = getPixelColor(device, 512+4, 64+4);
8716     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8717
8718     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8719      * Don't be overly picky - just show that the point is bigger than 1 pixel
8720      */
8721     color = getPixelColor(device, 576-4, 64-4);
8722     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8723     color = getPixelColor(device, 576+4, 64+4);
8724     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8725
8726     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8727      * generates texture coordinates for the point(result: Yes, it does)
8728      *
8729      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8730      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8731      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8732      */
8733     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8735
8736     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8738     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8739     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8740     memset(&lr, 0, sizeof(lr));
8741     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8742     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8743     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8744     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8745     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8746     memset(&lr, 0, sizeof(lr));
8747     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8748     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8749     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8750     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8751     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8752     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8753     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8754     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8755     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8756     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8757     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8758     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8759     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8760     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8761     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8762     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8763     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8764     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8765     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8766
8767     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8768     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8769     ptsize = 32.0;
8770     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8771     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8772
8773     hr = IDirect3DDevice9_BeginScene(device);
8774     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8775     if(SUCCEEDED(hr))
8776     {
8777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8778         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8779         hr = IDirect3DDevice9_EndScene(device);
8780         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8781     }
8782
8783     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8784     color = getPixelColor(device, 64-4, 64-4);
8785     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8786     color = getPixelColor(device, 64-4, 64+4);
8787     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8788     color = getPixelColor(device, 64+4, 64+4);
8789     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8790     color = getPixelColor(device, 64+4, 64-4);
8791     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8792
8793     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8794     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8795     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8796     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8797     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8798     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8799     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8801     IDirect3DTexture9_Release(tex1);
8802     IDirect3DTexture9_Release(tex2);
8803
8804     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8805     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8806     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8807     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8808     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8809     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8810 }
8811
8812 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8813 {
8814     HRESULT hr;
8815     IDirect3DPixelShader9 *ps;
8816     IDirect3DTexture9 *tex1, *tex2;
8817     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8818     D3DCAPS9 caps;
8819     DWORD color;
8820     DWORD shader_code[] = {
8821     0xffff0300,                                                             /* ps_3_0             */
8822     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8823     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8824     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8825     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8826     0x0000ffff                                                              /* END                */
8827     };
8828     float quad[] = {
8829        -1.0,   -1.0,    0.1,
8830         1.0,   -1.0,    0.1,
8831        -1.0,    1.0,    0.1,
8832         1.0,    1.0,    0.1,
8833     };
8834     float texquad[] = {
8835        -1.0,   -1.0,    0.1,    0.0,    0.0,
8836         0.0,   -1.0,    0.1,    1.0,    0.0,
8837        -1.0,    1.0,    0.1,    0.0,    1.0,
8838         0.0,    1.0,    0.1,    1.0,    1.0,
8839
8840         0.0,   -1.0,    0.1,    0.0,    0.0,
8841         1.0,   -1.0,    0.1,    1.0,    0.0,
8842         0.0,    1.0,    0.1,    0.0,    1.0,
8843         1.0,    1.0,    0.1,    1.0,    1.0,
8844     };
8845
8846     memset(&caps, 0, sizeof(caps));
8847     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8848     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8849     if(caps.NumSimultaneousRTs < 2) {
8850         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8851         return;
8852     }
8853
8854     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8855     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8856
8857     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8858     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8859     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8860     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8861     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8862     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8863
8864     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8865     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8866     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8867     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8868     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8869     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8870
8871     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8872     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8873     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8874     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8875     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8876     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8877     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8878     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8879
8880     hr = IDirect3DDevice9_BeginScene(device);
8881     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8882     if(SUCCEEDED(hr)) {
8883         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8884         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8885
8886         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8887         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8888         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8889         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8890         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8891         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8892         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8893         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8894
8895         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8896         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8897         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8898         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8899
8900         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8901         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8902         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8903         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8904
8905         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8906         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8907
8908         hr = IDirect3DDevice9_EndScene(device);
8909         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8910     }
8911
8912     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8913     color = getPixelColor(device, 160, 240);
8914     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8915     color = getPixelColor(device, 480, 240);
8916     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8917
8918     IDirect3DPixelShader9_Release(ps);
8919     IDirect3DTexture9_Release(tex1);
8920     IDirect3DTexture9_Release(tex2);
8921     IDirect3DSurface9_Release(surf1);
8922     IDirect3DSurface9_Release(surf2);
8923     IDirect3DSurface9_Release(backbuf);
8924 }
8925
8926 struct formats {
8927     const char *fmtName;
8928     D3DFORMAT textureFormat;
8929     DWORD resultColorBlending;
8930     DWORD resultColorNoBlending;
8931 };
8932
8933 const struct formats test_formats[] = {
8934   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8935   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8936   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8937   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8938   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8939   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8940   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8941   { NULL, 0 }
8942 };
8943
8944 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8945 {
8946     HRESULT hr;
8947     IDirect3DTexture9 *offscreenTexture = NULL;
8948     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8949     IDirect3D9 *d3d = NULL;
8950     DWORD color;
8951     DWORD r0, g0, b0, r1, g1, b1;
8952     int fmt_index;
8953
8954     static const float quad[][5] = {
8955         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8956         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8957         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8958         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8959     };
8960
8961     /* Quad with R=0x10, G=0x20 */
8962     static const struct vertex quad1[] = {
8963         {-1.0f, -1.0f, 0.1f, 0x80102000},
8964         {-1.0f,  1.0f, 0.1f, 0x80102000},
8965         { 1.0f, -1.0f, 0.1f, 0x80102000},
8966         { 1.0f,  1.0f, 0.1f, 0x80102000},
8967     };
8968
8969     /* Quad with R=0x20, G=0x10 */
8970     static const struct vertex quad2[] = {
8971         {-1.0f, -1.0f, 0.1f, 0x80201000},
8972         {-1.0f,  1.0f, 0.1f, 0x80201000},
8973         { 1.0f, -1.0f, 0.1f, 0x80201000},
8974         { 1.0f,  1.0f, 0.1f, 0x80201000},
8975     };
8976
8977     IDirect3DDevice9_GetDirect3D(device, &d3d);
8978
8979     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8980     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8981     if(!backbuffer) {
8982         goto out;
8983     }
8984
8985     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8986     {
8987         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8988         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8989            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8990            continue;
8991         }
8992
8993         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8994         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8995
8996         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8997         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8998         if(!offscreenTexture) {
8999             continue;
9000         }
9001
9002         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9003         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9004         if(!offscreen) {
9005             continue;
9006         }
9007
9008         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9009         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9010
9011         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9012         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9013         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9014         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9015         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9016         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9017         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9018         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9020         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9021
9022         /* Below we will draw two quads with different colors and try to blend them together.
9023          * The result color is compared with the expected outcome.
9024          */
9025         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9026             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9027             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9028             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9029             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9030
9031             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9032             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9033
9034             /* Draw a quad using color 0x0010200 */
9035             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9036             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9037             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9038             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9039             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9040             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9041
9042             /* Draw a quad using color 0x0020100 */
9043             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9044             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9045             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9046             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9047             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9048             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9049
9050             /* We don't want to blend the result on the backbuffer */
9051             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9052             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9053
9054             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9055             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9056             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9057             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9058             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9059
9060             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9061             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9062
9063             /* This time with the texture */
9064             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9065             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9066
9067             IDirect3DDevice9_EndScene(device);
9068         }
9069         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9070
9071
9072         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9073             /* Compare the color of the center quad with our expectation */
9074             color = getPixelColor(device, 320, 240);
9075             r0 = (color & 0x00ff0000) >> 16;
9076             g0 = (color & 0x0000ff00) >>  8;
9077             b0 = (color & 0x000000ff) >>  0;
9078
9079             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9080             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9081             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9082
9083             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9084                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9085                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9086                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9087         } else {
9088             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9089              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9090              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9091             color = getPixelColor(device, 320, 240);
9092             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);
9093         }
9094
9095         IDirect3DDevice9_SetTexture(device, 0, NULL);
9096         if(offscreenTexture) {
9097             IDirect3DTexture9_Release(offscreenTexture);
9098         }
9099         if(offscreen) {
9100             IDirect3DSurface9_Release(offscreen);
9101         }
9102     }
9103
9104 out:
9105     /* restore things */
9106     if(backbuffer) {
9107         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9108         IDirect3DSurface9_Release(backbuffer);
9109     }
9110 }
9111
9112 static void tssargtemp_test(IDirect3DDevice9 *device)
9113 {
9114     HRESULT hr;
9115     DWORD color;
9116     static const struct vertex quad[] = {
9117         {-1.0,     -1.0,    0.1,    0x00ff0000},
9118         { 1.0,     -1.0,    0.1,    0x00ff0000},
9119         {-1.0,      1.0,    0.1,    0x00ff0000},
9120         { 1.0,      1.0,    0.1,    0x00ff0000}
9121     };
9122     D3DCAPS9 caps;
9123
9124     memset(&caps, 0, sizeof(caps));
9125     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9126     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9127     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9128         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9129         return;
9130     }
9131
9132     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9133     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9134
9135     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9136     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9137     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9138     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9139
9140     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9141     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9142     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9143     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9144     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9145     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9146
9147     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9148     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9149     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9150     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9151     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9152     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9153
9154     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9155     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9156
9157     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9158     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9159     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9160     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9161
9162     hr = IDirect3DDevice9_BeginScene(device);
9163     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9164     if(SUCCEEDED(hr)) {
9165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9166         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9167         hr = IDirect3DDevice9_EndScene(device);
9168         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9169     }
9170     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9171     color = getPixelColor(device, 320, 240);
9172     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9173
9174     /* Set stage 1 back to default */
9175     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9176     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9177     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9178     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9179     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9180     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9181     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9182     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9183     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9184     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9185 }
9186
9187 struct testdata
9188 {
9189     DWORD idxVertex; /* number of instances in the first stream */
9190     DWORD idxColor; /* number of instances in the second stream */
9191     DWORD idxInstance; /* should be 1 ?? */
9192     DWORD color1; /* color 1 instance */
9193     DWORD color2; /* color 2 instance */
9194     DWORD color3; /* color 3 instance */
9195     DWORD color4; /* color 4 instance */
9196     WORD strVertex; /* specify which stream to use 0-2*/
9197     WORD strColor;
9198     WORD strInstance;
9199 };
9200
9201 static const struct testdata testcases[]=
9202 {
9203     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9204     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9205     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9206     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9207     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9208     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9209     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9210     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9211     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9212     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9213     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9214     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9215     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9216     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9217     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9218 /*
9219     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9220     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9221 */
9222 };
9223
9224 /* Drawing Indexed Geometry with instances*/
9225 static void stream_test(IDirect3DDevice9 *device)
9226 {
9227     IDirect3DVertexBuffer9 *vb = NULL;
9228     IDirect3DVertexBuffer9 *vb2 = NULL;
9229     IDirect3DVertexBuffer9 *vb3 = NULL;
9230     IDirect3DIndexBuffer9 *ib = NULL;
9231     IDirect3DVertexDeclaration9 *pDecl = NULL;
9232     IDirect3DVertexShader9 *shader = NULL;
9233     HRESULT hr;
9234     BYTE *data;
9235     DWORD color;
9236     DWORD ind;
9237     unsigned i;
9238
9239     const DWORD shader_code[] =
9240     {
9241         0xfffe0101,                                     /* vs_1_1 */
9242         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9243         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9244         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9245         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9246         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9247         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9248         0x0000ffff
9249     };
9250
9251     const float quad[][3] =
9252     {
9253         {-0.5f, -0.5f,  1.1f}, /*0 */
9254         {-0.5f,  0.5f,  1.1f}, /*1 */
9255         { 0.5f, -0.5f,  1.1f}, /*2 */
9256         { 0.5f,  0.5f,  1.1f}, /*3 */
9257     };
9258
9259     const float vertcolor[][4] =
9260     {
9261         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9262         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9263         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9264         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9265     };
9266
9267     /* 4 position for 4 instances */
9268     const float instancepos[][3] =
9269     {
9270         {-0.6f,-0.6f, 0.0f},
9271         { 0.6f,-0.6f, 0.0f},
9272         { 0.6f, 0.6f, 0.0f},
9273         {-0.6f, 0.6f, 0.0f},
9274     };
9275
9276     short indices[] = {0, 1, 2, 1, 2, 3};
9277
9278     D3DVERTEXELEMENT9 decl[] =
9279     {
9280         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9281         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9282         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9283         D3DDECL_END()
9284     };
9285
9286     /* set the default value because it isn't done in wine? */
9287     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9288     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9289
9290     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9291     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9292     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9293
9294     /* check wrong cases */
9295     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9296     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9297     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9298     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9299     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9300     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9301     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9302     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9303     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9304     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9305     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9306     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9307     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9308     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9309     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9310     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9311     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9312     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9313     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9314     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9315
9316     /* set the default value back */
9317     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9318     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9319
9320     /* create all VertexBuffers*/
9321     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9322     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9323     if(!vb) {
9324         skip("Failed to create a vertex buffer\n");
9325         return;
9326     }
9327     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9328     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9329     if(!vb2) {
9330         skip("Failed to create a vertex buffer\n");
9331         goto out;
9332     }
9333     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9334     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9335     if(!vb3) {
9336         skip("Failed to create a vertex buffer\n");
9337         goto out;
9338     }
9339
9340     /* create IndexBuffer*/
9341     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9343     if(!ib) {
9344         skip("Failed to create a index buffer\n");
9345         goto out;
9346     }
9347
9348     /* copy all Buffers (Vertex + Index)*/
9349     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9350     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9351     memcpy(data, quad, sizeof(quad));
9352     hr = IDirect3DVertexBuffer9_Unlock(vb);
9353     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9354     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9355     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9356     memcpy(data, vertcolor, sizeof(vertcolor));
9357     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9358     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9359     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9360     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9361     memcpy(data, instancepos, sizeof(instancepos));
9362     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9363     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9364     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9365     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9366     memcpy(data, indices, sizeof(indices));
9367     hr = IDirect3DIndexBuffer9_Unlock(ib);
9368     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9369
9370     /* create VertexShader */
9371     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9372     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9373     if(!shader) {
9374         skip("Failed to create a vetex shader\n");
9375         goto out;
9376     }
9377
9378     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9379     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9380
9381     hr = IDirect3DDevice9_SetIndices(device, ib);
9382     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9383
9384     /* run all tests */
9385     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9386     {
9387         struct testdata act = testcases[i];
9388         decl[0].Stream = act.strVertex;
9389         decl[1].Stream = act.strColor;
9390         decl[2].Stream = act.strInstance;
9391         /* create VertexDeclarations */
9392         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9393         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9394
9395         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9396         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9397
9398         hr = IDirect3DDevice9_BeginScene(device);
9399         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9400         if(SUCCEEDED(hr))
9401         {
9402             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9403             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9404
9405             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9406             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9407             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9408             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9409
9410             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9411             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9412             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9413             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9414
9415             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9416             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9417             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9418             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9419
9420             /* don't know if this is right (1*3 and 4*1)*/
9421             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9422             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9423             hr = IDirect3DDevice9_EndScene(device);
9424             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9425
9426             /* set all StreamSource && StreamSourceFreq back to default */
9427             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9428             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9429             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9430             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9431             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9432             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9433             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9434             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9435             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9436             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9437             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9438             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9439         }
9440
9441         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9442         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9443
9444         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9445         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9446
9447         color = getPixelColor(device, 160, 360);
9448         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9449         color = getPixelColor(device, 480, 360);
9450         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9451         color = getPixelColor(device, 480, 120);
9452         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9453         color = getPixelColor(device, 160, 120);
9454         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9455     }
9456
9457     hr = IDirect3DDevice9_SetIndices(device, NULL);
9458     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9459
9460 out:
9461     if(vb) IDirect3DVertexBuffer9_Release(vb);
9462     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9463     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9464     if(ib)IDirect3DIndexBuffer9_Release(ib);
9465     if(shader)IDirect3DVertexShader9_Release(shader);
9466 }
9467
9468 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9469     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9470     IDirect3DTexture9 *dsttex = NULL;
9471     HRESULT hr;
9472     DWORD color;
9473     D3DRECT r1 = {0,  0,  50,  50 };
9474     D3DRECT r2 = {50, 0,  100, 50 };
9475     D3DRECT r3 = {50, 50, 100, 100};
9476     D3DRECT r4 = {0,  50,  50, 100};
9477     const float quad[] = {
9478         -1.0,   -1.0,   0.1,    0.0,    0.0,
9479          1.0,   -1.0,   0.1,    1.0,    0.0,
9480         -1.0,    1.0,   0.1,    0.0,    1.0,
9481          1.0,    1.0,   0.1,    1.0,    1.0,
9482     };
9483
9484     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9485     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9486
9487     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9488     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9489     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9490     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9491
9492     if(!src || !dsttex) {
9493         skip("One or more test resources could not be created\n");
9494         goto cleanup;
9495     }
9496
9497     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9498     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9499
9500     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9502
9503     /* Clear the StretchRect destination for debugging */
9504     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9505     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9506     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9508
9509     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9511
9512     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9513     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9514     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9515     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9516     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9517     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9518     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9519     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9520
9521     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9522      * the target -> texture GL blit path
9523      */
9524     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9525     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9526     IDirect3DSurface9_Release(dst);
9527
9528     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9529     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9530
9531     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9532     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9533     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9534     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9535     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9536     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9537     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9538     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9539
9540     hr = IDirect3DDevice9_BeginScene(device);
9541     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9542     if(SUCCEEDED(hr)) {
9543         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9544         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9545         hr = IDirect3DDevice9_EndScene(device);
9546         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9547     }
9548
9549     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9550     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9551     color = getPixelColor(device, 160, 360);
9552     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9553     color = getPixelColor(device, 480, 360);
9554     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9555     color = getPixelColor(device, 480, 120);
9556     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9557     color = getPixelColor(device, 160, 120);
9558     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9559
9560     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9561     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9562     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9563     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9564
9565 cleanup:
9566     if(src) IDirect3DSurface9_Release(src);
9567     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9568     if(dsttex) IDirect3DTexture9_Release(dsttex);
9569 }
9570
9571 static void texop_test(IDirect3DDevice9 *device)
9572 {
9573     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9574     IDirect3DTexture9 *texture = NULL;
9575     D3DLOCKED_RECT locked_rect;
9576     D3DCOLOR color;
9577     D3DCAPS9 caps;
9578     HRESULT hr;
9579     unsigned i;
9580
9581     static const struct {
9582         float x, y, z;
9583         float s, t;
9584         D3DCOLOR diffuse;
9585     } quad[] = {
9586         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9587         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9588         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9589         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9590     };
9591
9592     static const D3DVERTEXELEMENT9 decl_elements[] = {
9593         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9594         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9595         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9596         D3DDECL_END()
9597     };
9598
9599     static const struct {
9600         D3DTEXTUREOP op;
9601         const char *name;
9602         DWORD caps_flag;
9603         D3DCOLOR result;
9604     } test_data[] = {
9605         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9606         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9607         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9608         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9609         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9610         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9611         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9612         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9613         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9614         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9615         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9616         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9617         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9618         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9619         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9620         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9621         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9622         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9623         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9624         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9625         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9626         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9627         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9628     };
9629
9630     memset(&caps, 0, sizeof(caps));
9631     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9632     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9633
9634     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9635     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9636     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9637     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9638
9639     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9640     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9641     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9642     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9643     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9644     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9645     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9646     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9647     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9648
9649     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9650     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9651     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9652     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9653     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9654     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9655
9656     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9657     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9658
9659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9660     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9662     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9664     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9665
9666     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9667     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9668
9669     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9670     {
9671         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9672         {
9673             skip("tex operation %s not supported\n", test_data[i].name);
9674             continue;
9675         }
9676
9677         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9678         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9679
9680         hr = IDirect3DDevice9_BeginScene(device);
9681         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9682
9683         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9684         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9685
9686         hr = IDirect3DDevice9_EndScene(device);
9687         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9688
9689         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9690         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9691
9692         color = getPixelColor(device, 320, 240);
9693         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9694                 test_data[i].name, color, test_data[i].result);
9695     }
9696
9697     if (texture) IDirect3DTexture9_Release(texture);
9698     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9699 }
9700
9701 static void yuv_color_test(IDirect3DDevice9 *device) {
9702     HRESULT hr;
9703     IDirect3DSurface9 *surface = NULL, *target = NULL;
9704     unsigned int fmt, i;
9705     D3DFORMAT format;
9706     const char *fmt_string;
9707     D3DLOCKED_RECT lr;
9708     IDirect3D9 *d3d;
9709     HRESULT color;
9710     DWORD ref_color_left, ref_color_right;
9711
9712     struct {
9713         DWORD in;           /* The input color */
9714         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9715         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9716         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9717         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9718     } test_data[] = {
9719     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9720      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9721      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9722      * that
9723      */
9724       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9725       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9726       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9727       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9728       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9729       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9730       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9731       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9732       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9733       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9734       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9735       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9736       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9737       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9738
9739       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9740       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9741       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9742       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9743     };
9744
9745     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9746     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9747     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9748     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9749
9750     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9751     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9752
9753     for(fmt = 0; fmt < 2; fmt++) {
9754         if(fmt == 0) {
9755             format = D3DFMT_UYVY;
9756             fmt_string = "D3DFMT_UYVY";
9757         } else {
9758             format = D3DFMT_YUY2;
9759             fmt_string = "D3DFMT_YUY2";
9760         }
9761
9762         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9763                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9764                        */
9765         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9766                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9767             skip("%s is not supported\n", fmt_string);
9768             continue;
9769         }
9770
9771         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9772         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9773         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9774
9775         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9776             if(fmt == 0) {
9777                 ref_color_left = test_data[i].uyvy_left;
9778                 ref_color_right = test_data[i].uyvy_right;
9779             } else {
9780                 ref_color_left = test_data[i].yuy2_left;
9781                 ref_color_right = test_data[i].yuy2_right;
9782             }
9783
9784             memset(&lr, 0, sizeof(lr));
9785             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9786             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9787             *((DWORD *) lr.pBits) = test_data[i].in;
9788             hr = IDirect3DSurface9_UnlockRect(surface);
9789             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9790
9791             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9792             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9793             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9794             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9795             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9796             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9797
9798             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9799              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9800              * want to add tests for the filtered pixels as well.
9801              *
9802              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9803              * differently, so we need a max diff of 16
9804              */
9805             color = getPixelColor(device, 40, 240);
9806             ok(color_match(color, ref_color_left, 18),
9807                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9808                test_data[i].in, color, ref_color_left, fmt_string);
9809             color = getPixelColor(device, 600, 240);
9810             ok(color_match(color, ref_color_right, 18),
9811                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9812                test_data[i].in, color, ref_color_right, fmt_string);
9813         }
9814         IDirect3DSurface9_Release(surface);
9815     }
9816     IDirect3DSurface9_Release(target);
9817     IDirect3D9_Release(d3d);
9818 }
9819
9820 static void texop_range_test(IDirect3DDevice9 *device)
9821 {
9822     static const struct {
9823         float x, y, z;
9824         D3DCOLOR diffuse;
9825     } quad[] = {
9826         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9827         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9828         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9829         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9830     };
9831     HRESULT hr;
9832     IDirect3DTexture9 *texture;
9833     D3DLOCKED_RECT locked_rect;
9834     D3DCAPS9 caps;
9835     DWORD color;
9836
9837     /* We need ADD and SUBTRACT operations */
9838     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9839     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9840     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9841         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9842         return;
9843     }
9844     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9845         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9846         return;
9847     }
9848
9849     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9850     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9851     /* Stage 1: result = diffuse(=1.0) + diffuse
9852      * stage 2: result = result - tfactor(= 0.5)
9853      */
9854     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9855     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9856     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9857     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9858     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9859     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9860     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9861     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9862     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9863     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9864     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9865     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9866     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9867     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9868
9869     hr = IDirect3DDevice9_BeginScene(device);
9870     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9871     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9872     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9873     hr = IDirect3DDevice9_EndScene(device);
9874     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9875     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9876     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9877
9878     color = getPixelColor(device, 320, 240);
9879     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9880        color);
9881
9882     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9883     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9884     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9885     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9886     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9887     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9888     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9889     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9890     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9891
9892     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9893      * stage 2: result = result + diffuse(1.0)
9894      */
9895     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9896     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9897     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9898     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9899     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9900     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9901     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9902     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9903     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9904     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9905     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9906     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9907     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9908     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9909
9910     hr = IDirect3DDevice9_BeginScene(device);
9911     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9912     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9913     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9914     hr = IDirect3DDevice9_EndScene(device);
9915     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9916     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9917     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9918
9919     color = getPixelColor(device, 320, 240);
9920     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9921        color);
9922
9923     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9924     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9925     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9926     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9927     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9928     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9929     IDirect3DTexture9_Release(texture);
9930 }
9931
9932 static void alphareplicate_test(IDirect3DDevice9 *device) {
9933     struct vertex quad[] = {
9934         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9935         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9936         { -1.0,     1.0,    0.1,    0x80ff00ff },
9937         {  1.0,     1.0,    0.1,    0x80ff00ff },
9938     };
9939     HRESULT hr;
9940     DWORD color;
9941
9942     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9943     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9944
9945     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9946     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9947
9948     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9949     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9950     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9951     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9952
9953     hr = IDirect3DDevice9_BeginScene(device);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9955     if(SUCCEEDED(hr)) {
9956         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9957         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9958         hr = IDirect3DDevice9_EndScene(device);
9959         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9960     }
9961
9962     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9964
9965     color = getPixelColor(device, 320, 240);
9966     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9967        color);
9968
9969     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9970     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9971
9972 }
9973
9974 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9975     HRESULT hr;
9976     D3DCAPS9 caps;
9977     DWORD color;
9978     struct vertex quad[] = {
9979         { -1.0,    -1.0,    0.1,    0x408080c0 },
9980         {  1.0,    -1.0,    0.1,    0x408080c0 },
9981         { -1.0,     1.0,    0.1,    0x408080c0 },
9982         {  1.0,     1.0,    0.1,    0x408080c0 },
9983     };
9984
9985     memset(&caps, 0, sizeof(caps));
9986     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9987     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9988     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9989         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9990         return;
9991     }
9992
9993     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9994     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9995
9996     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9997     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9998
9999     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10000      * mov r0.a, diffuse.a
10001      * mov r0, r0.a
10002      *
10003      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10004      * 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
10005      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10006      */
10007     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10008     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10009     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10010     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10011     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10012     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10013     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10014     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10015     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10016     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10017     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10018     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10019     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10020     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10021     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10022     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10025
10026     hr = IDirect3DDevice9_BeginScene(device);
10027     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10028     if(SUCCEEDED(hr)) {
10029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10030         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10031         hr = IDirect3DDevice9_EndScene(device);
10032         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10033     }
10034
10035     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10036     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10037
10038     color = getPixelColor(device, 320, 240);
10039     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10040        color);
10041
10042     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10043     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10044     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10045     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10046     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10047     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10048 }
10049
10050 static void zwriteenable_test(IDirect3DDevice9 *device) {
10051     HRESULT hr;
10052     DWORD color;
10053     struct vertex quad1[] = {
10054         { -1.0,  -1.0,  0.1,    0x00ff0000},
10055         { -1.0,   1.0,  0.1,    0x00ff0000},
10056         {  1.0,  -1.0,  0.1,    0x00ff0000},
10057         {  1.0,   1.0,  0.1,    0x00ff0000},
10058     };
10059     struct vertex quad2[] = {
10060         { -1.0,  -1.0,  0.9,    0x0000ff00},
10061         { -1.0,   1.0,  0.9,    0x0000ff00},
10062         {  1.0,  -1.0,  0.9,    0x0000ff00},
10063         {  1.0,   1.0,  0.9,    0x0000ff00},
10064     };
10065
10066     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10067     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10068
10069     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10070     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10071     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10072     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10073     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10074     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10076     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10077
10078     hr = IDirect3DDevice9_BeginScene(device);
10079     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10080     if(SUCCEEDED(hr)) {
10081         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10082          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10083          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10084          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10085          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10086          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10087          */
10088         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10089         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10090         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10091         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10092         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10093         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10094
10095         hr = IDirect3DDevice9_EndScene(device);
10096         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10097     }
10098
10099     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10100     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10101     color = getPixelColor(device, 320, 240);
10102     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10103        color);
10104
10105     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10106     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10107 }
10108
10109 static void alphatest_test(IDirect3DDevice9 *device) {
10110 #define ALPHATEST_PASSED 0x0000ff00
10111 #define ALPHATEST_FAILED 0x00ff0000
10112     struct {
10113         D3DCMPFUNC  func;
10114         DWORD       color_less;
10115         DWORD       color_equal;
10116         DWORD       color_greater;
10117     } testdata[] = {
10118         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10119         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10120         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10121         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10122         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10123         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10124         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10125         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10126     };
10127     unsigned int i, j;
10128     HRESULT hr;
10129     DWORD color;
10130     struct vertex quad[] = {
10131         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10132         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10133         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10134         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10135     };
10136     D3DCAPS9 caps;
10137
10138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10140     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10141     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10142
10143     for(j = 0; j < 2; j++) {
10144         if(j == 1) {
10145             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10146              * the alpha test either for performance reasons(floating point RTs) or to work
10147              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10148              * codepath for ffp and shader in this case, and the test should cover both
10149              */
10150             IDirect3DPixelShader9 *ps;
10151             DWORD shader_code[] = {
10152                 0xffff0101,                                 /* ps_1_1           */
10153                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10154                 0x0000ffff                                  /* end              */
10155             };
10156             memset(&caps, 0, sizeof(caps));
10157             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10158             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10159             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10160                 break;
10161             }
10162
10163             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10164             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10165             IDirect3DDevice9_SetPixelShader(device, ps);
10166             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10167             IDirect3DPixelShader9_Release(ps);
10168         }
10169
10170         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10171             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10172             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10173
10174             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10175             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10176             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10177             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10178             hr = IDirect3DDevice9_BeginScene(device);
10179             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10180             if(SUCCEEDED(hr)) {
10181                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10182                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10183                 hr = IDirect3DDevice9_EndScene(device);
10184                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10185             }
10186             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10187             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10188             color = getPixelColor(device, 320, 240);
10189             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10190             color, testdata[i].color_less, testdata[i].func);
10191
10192             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10193             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10194             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10195             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10196             hr = IDirect3DDevice9_BeginScene(device);
10197             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10198             if(SUCCEEDED(hr)) {
10199                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10200                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10201                 hr = IDirect3DDevice9_EndScene(device);
10202                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10203             }
10204             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10205             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10206             color = getPixelColor(device, 320, 240);
10207             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10208             color, testdata[i].color_equal, testdata[i].func);
10209
10210             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10211             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10212             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10213             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10214             hr = IDirect3DDevice9_BeginScene(device);
10215             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10216             if(SUCCEEDED(hr)) {
10217                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10218                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10219                 hr = IDirect3DDevice9_EndScene(device);
10220                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10221             }
10222             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10223             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10224             color = getPixelColor(device, 320, 240);
10225             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10226             color, testdata[i].color_greater, testdata[i].func);
10227         }
10228     }
10229
10230     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10231     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10232     IDirect3DDevice9_SetPixelShader(device, NULL);
10233     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10234 }
10235
10236 static void sincos_test(IDirect3DDevice9 *device) {
10237     const DWORD sin_shader_code[] = {
10238         0xfffe0200,                                                                 /* vs_2_0                       */
10239         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10240         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10241         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10242         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10243         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10244         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10245         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10246         0x0000ffff                                                                  /* end                          */
10247     };
10248     const DWORD cos_shader_code[] = {
10249         0xfffe0200,                                                                 /* vs_2_0                       */
10250         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10251         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10252         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10253         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10254         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10255         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10256         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10257         0x0000ffff                                                                  /* end                          */
10258     };
10259     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10260     HRESULT hr;
10261     struct {
10262         float x, y, z;
10263     } data[1280];
10264     unsigned int i;
10265     float sincosc1[4] = {D3DSINCOSCONST1};
10266     float sincosc2[4] = {D3DSINCOSCONST2};
10267
10268     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10269     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10270
10271     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10272     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10273     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10274     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10275     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10277     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10279     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10280     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10281
10282     /* Generate a point from -1 to 1 every 0.5 pixels */
10283     for(i = 0; i < 1280; i++) {
10284         data[i].x = (-640.0 + i) / 640.0;
10285         data[i].y = 0.0;
10286         data[i].z = 0.1;
10287     }
10288
10289     hr = IDirect3DDevice9_BeginScene(device);
10290     if(SUCCEEDED(hr)) {
10291         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10292         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10293         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10294         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10295
10296         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10297         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10298         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10299         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10300
10301         hr = IDirect3DDevice9_EndScene(device);
10302         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10303     }
10304     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10305     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10306     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10307
10308     IDirect3DDevice9_SetVertexShader(device, NULL);
10309     IDirect3DVertexShader9_Release(sin_shader);
10310     IDirect3DVertexShader9_Release(cos_shader);
10311 }
10312
10313 static void loop_index_test(IDirect3DDevice9 *device) {
10314     const DWORD shader_code[] = {
10315         0xfffe0200,                                                 /* vs_2_0                   */
10316         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10317         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10318         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10319         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10320         0x0000001d,                                                 /* endloop                  */
10321         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10322         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10323         0x0000ffff                                                  /* END                      */
10324     };
10325     IDirect3DVertexShader9 *shader;
10326     HRESULT hr;
10327     DWORD color;
10328     const float quad[] = {
10329         -1.0,   -1.0,   0.1,
10330          1.0,   -1.0,   0.1,
10331         -1.0,    1.0,   0.1,
10332          1.0,    1.0,   0.1
10333     };
10334     const float zero[4] = {0, 0, 0, 0};
10335     const float one[4] = {1, 1, 1, 1};
10336     int i0[4] = {2, 10, -3, 0};
10337     float values[4];
10338
10339     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10341     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10342     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10343     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10344     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10345     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10346     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10347
10348     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10349     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10350     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10351     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10352     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10353     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10354     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10355     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10356     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10357     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10358     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10359     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10360     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10361     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10362     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10363     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10364     values[0] = 1.0;
10365     values[1] = 1.0;
10366     values[2] = 0.0;
10367     values[3] = 0.0;
10368     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10369     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10370     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10371     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10372     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10373     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10374     values[0] = -1.0;
10375     values[1] = 0.0;
10376     values[2] = 0.0;
10377     values[3] = 0.0;
10378     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10379     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10380     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10381     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10382     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10383     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10384     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10385     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10386     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10387     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10388
10389     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10390     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10391
10392     hr = IDirect3DDevice9_BeginScene(device);
10393     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10394     if(SUCCEEDED(hr))
10395     {
10396         trace("going to draw index\n");
10397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10398         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10399         hr = IDirect3DDevice9_EndScene(device);
10400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10401     }
10402     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10403     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10404
10405     color = getPixelColor(device, 320, 240);
10406     ok(color_match(color, 0x0000ff00, 1),
10407        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10408
10409     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10410     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10411     IDirect3DVertexShader9_Release(shader);
10412 }
10413
10414 static void sgn_test(IDirect3DDevice9 *device) {
10415     const DWORD shader_code[] = {
10416         0xfffe0200,                                                             /* vs_2_0                       */
10417         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10418         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10419         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10420         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10421         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10422         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10423         0x0000ffff                                                              /* end                          */
10424     };
10425     IDirect3DVertexShader9 *shader;
10426     HRESULT hr;
10427     DWORD color;
10428     const float quad[] = {
10429         -1.0,   -1.0,   0.1,
10430          1.0,   -1.0,   0.1,
10431         -1.0,    1.0,   0.1,
10432          1.0,    1.0,   0.1
10433     };
10434
10435     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10436     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10437     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10438     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10439     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10440     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10441     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10442     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10443
10444     hr = IDirect3DDevice9_BeginScene(device);
10445     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10446     if(SUCCEEDED(hr))
10447     {
10448         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10449         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10450         hr = IDirect3DDevice9_EndScene(device);
10451         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10452     }
10453     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10454     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10455
10456     color = getPixelColor(device, 320, 240);
10457     ok(color_match(color, 0x008000ff, 1),
10458        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10459
10460     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10461     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10462     IDirect3DVertexShader9_Release(shader);
10463 }
10464
10465 static void viewport_test(IDirect3DDevice9 *device) {
10466     HRESULT hr;
10467     DWORD color;
10468     D3DVIEWPORT9 vp, old_vp;
10469     const float quad[] =
10470     {
10471         -0.5,   -0.5,   0.1,
10472          0.5,   -0.5,   0.1,
10473         -0.5,    0.5,   0.1,
10474          0.5,    0.5,   0.1
10475     };
10476
10477     memset(&old_vp, 0, sizeof(old_vp));
10478     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10479     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10480
10481     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10482     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10483
10484     /* Test a viewport with Width and Height bigger than the surface dimensions
10485      *
10486      * TODO: Test Width < surface.width, but X + Width > surface.width
10487      * TODO: Test Width < surface.width, what happens with the height?
10488      */
10489     memset(&vp, 0, sizeof(vp));
10490     vp.X = 0;
10491     vp.Y = 0;
10492     vp.Width = 10000;
10493     vp.Height = 10000;
10494     vp.MinZ = 0.0;
10495     vp.MaxZ = 0.0;
10496     hr = IDirect3DDevice9_SetViewport(device, &vp);
10497     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10498
10499     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10500     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10501     hr = IDirect3DDevice9_BeginScene(device);
10502     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10503     if(SUCCEEDED(hr))
10504     {
10505         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10506         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10507         hr = IDirect3DDevice9_EndScene(device);
10508         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10509     }
10510     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10511
10512     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10513     color = getPixelColor(device, 158, 118);
10514     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10515     color = getPixelColor(device, 162, 118);
10516     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10517     color = getPixelColor(device, 158, 122);
10518     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10519     color = getPixelColor(device, 162, 122);
10520     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10521
10522     color = getPixelColor(device, 478, 358);
10523     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10524     color = getPixelColor(device, 482, 358);
10525     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10526     color = getPixelColor(device, 478, 362);
10527     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10528     color = getPixelColor(device, 482, 362);
10529     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10530
10531     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10532     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10533 }
10534
10535 START_TEST(visual)
10536 {
10537     IDirect3DDevice9 *device_ptr;
10538     D3DCAPS9 caps;
10539     HRESULT hr;
10540     DWORD color;
10541
10542     d3d9_handle = LoadLibraryA("d3d9.dll");
10543     if (!d3d9_handle)
10544     {
10545         skip("Could not load d3d9.dll\n");
10546         return;
10547     }
10548
10549     device_ptr = init_d3d9();
10550     if (!device_ptr)
10551     {
10552         skip("Creating the device failed\n");
10553         return;
10554     }
10555
10556     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10557
10558     /* Check for the reliability of the returned data */
10559     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10560     if(FAILED(hr))
10561     {
10562         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10563         goto cleanup;
10564     }
10565     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10566
10567     color = getPixelColor(device_ptr, 1, 1);
10568     if(color !=0x00ff0000)
10569     {
10570         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10571         goto cleanup;
10572     }
10573
10574     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10575     if(FAILED(hr))
10576     {
10577         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10578         goto cleanup;
10579     }
10580     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10581
10582     color = getPixelColor(device_ptr, 639, 479);
10583     if(color != 0x0000ddee)
10584     {
10585         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10586         goto cleanup;
10587     }
10588
10589     /* Now execute the real tests */
10590     stretchrect_test(device_ptr);
10591     lighting_test(device_ptr);
10592     clear_test(device_ptr);
10593     fog_test(device_ptr);
10594     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10595     {
10596         test_cube_wrap(device_ptr);
10597     } else {
10598         skip("No cube texture support\n");
10599     }
10600     z_range_test(device_ptr);
10601     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10602     {
10603         maxmip_test(device_ptr);
10604     }
10605     else
10606     {
10607         skip("No mipmap support\n");
10608     }
10609     offscreen_test(device_ptr);
10610     alpha_test(device_ptr);
10611     shademode_test(device_ptr);
10612     srgbtexture_test(device_ptr);
10613     release_buffer_test(device_ptr);
10614     float_texture_test(device_ptr);
10615     g16r16_texture_test(device_ptr);
10616     pixelshader_blending_test(device_ptr);
10617     texture_transform_flags_test(device_ptr);
10618     autogen_mipmap_test(device_ptr);
10619     fixed_function_decl_test(device_ptr);
10620     conditional_np2_repeat_test(device_ptr);
10621     fixed_function_bumpmap_test(device_ptr);
10622     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10623         stencil_cull_test(device_ptr);
10624     } else {
10625         skip("No two sided stencil support\n");
10626     }
10627     pointsize_test(device_ptr);
10628     tssargtemp_test(device_ptr);
10629     np2_stretch_rect_test(device_ptr);
10630     yuv_color_test(device_ptr);
10631     zwriteenable_test(device_ptr);
10632     alphatest_test(device_ptr);
10633     viewport_test(device_ptr);
10634
10635     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10636     {
10637         test_constant_clamp_vs(device_ptr);
10638         test_compare_instructions(device_ptr);
10639     }
10640     else skip("No vs_1_1 support\n");
10641
10642     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10643     {
10644         test_mova(device_ptr);
10645         loop_index_test(device_ptr);
10646         sincos_test(device_ptr);
10647         sgn_test(device_ptr);
10648         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10649             test_vshader_input(device_ptr);
10650             test_vshader_float16(device_ptr);
10651             stream_test(device_ptr);
10652         } else {
10653             skip("No vs_3_0 support\n");
10654         }
10655     }
10656     else skip("No vs_2_0 support\n");
10657
10658     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10659     {
10660         fog_with_shader_test(device_ptr);
10661         fog_srgbwrite_test(device_ptr);
10662     }
10663     else skip("No vs_1_1 and ps_1_1 support\n");
10664
10665     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10666     {
10667         texbem_test(device_ptr);
10668         texdepth_test(device_ptr);
10669         texkill_test(device_ptr);
10670         x8l8v8u8_test(device_ptr);
10671         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10672             constant_clamp_ps_test(device_ptr);
10673             cnd_test(device_ptr);
10674             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10675                 dp2add_ps_test(device_ptr);
10676                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10677                     nested_loop_test(device_ptr);
10678                     fixed_function_varying_test(device_ptr);
10679                     vFace_register_test(device_ptr);
10680                     vpos_register_test(device_ptr);
10681                     multiple_rendertargets_test(device_ptr);
10682                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10683                         vshader_version_varying_test(device_ptr);
10684                         pshader_version_varying_test(device_ptr);
10685                     } else {
10686                         skip("No vs_3_0 support\n");
10687                     }
10688                 } else {
10689                     skip("No ps_3_0 support\n");
10690                 }
10691             } else {
10692                 skip("No ps_2_0 support\n");
10693             }
10694         }
10695     }
10696     else skip("No ps_1_1 support\n");
10697
10698     texop_test(device_ptr);
10699     texop_range_test(device_ptr);
10700     alphareplicate_test(device_ptr);
10701     dp3_alpha_test(device_ptr);
10702
10703 cleanup:
10704     if(device_ptr) {
10705         D3DPRESENT_PARAMETERS present_parameters;
10706         IDirect3DSwapChain9 *swapchain;
10707         ULONG ref;
10708
10709         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10710         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10711         DestroyWindow(present_parameters.hDeviceWindow);
10712         IDirect3DSwapChain9_Release(swapchain);
10713         ref = IDirect3DDevice9_Release(device_ptr);
10714         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10715     }
10716 }