crypt32: Make sure we show Unicode characters (Dutch translation).
[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     trace("Device name string: \"%s\"\n", identifier.DeviceName);
186     trace("Driver version %d.%d.%d.%d\n",
187           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
188           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
189
190     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191     if(FAILED(hr)) {
192         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
193         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
194         if(FAILED(hr)) {
195             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
196         }
197     }
198     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
199
200     return device_ptr;
201 }
202
203 struct vertex
204 {
205     float x, y, z;
206     DWORD diffuse;
207 };
208
209 struct tvertex
210 {
211     float x, y, z, rhw;
212     DWORD diffuse;
213 };
214
215 struct nvertex
216 {
217     float x, y, z;
218     float nx, ny, nz;
219     DWORD diffuse;
220 };
221
222 static void lighting_test(IDirect3DDevice9 *device)
223 {
224     HRESULT hr;
225     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
226     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
227     DWORD color;
228     D3DMATERIAL9 material, old_material;
229     DWORD cop, carg;
230
231     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
232                       0.0f, 1.0f, 0.0f, 0.0f,
233                       0.0f, 0.0f, 1.0f, 0.0f,
234                       0.0f, 0.0f, 0.0f, 1.0f };
235
236     struct vertex unlitquad[] =
237     {
238         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
239         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
240         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
241         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
242     };
243     struct vertex litquad[] =
244     {
245         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
246         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
247         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
248         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
249     };
250     struct nvertex unlitnquad[] =
251     {
252         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
253         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
254         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
255         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
256     };
257     struct nvertex litnquad[] =
258     {
259         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
260         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
261         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
262         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
263     };
264     WORD Indices[] = {0, 1, 2, 2, 3, 0};
265
266     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
267     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
268
269     /* Setup some states that may cause issues */
270     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
272     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
273     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
275     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
277     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
278     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
279     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
281     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
294
295     hr = IDirect3DDevice9_SetFVF(device, 0);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
297
298     hr = IDirect3DDevice9_SetFVF(device, fvf);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
300
301     hr = IDirect3DDevice9_BeginScene(device);
302     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
303     if(hr == D3D_OK)
304     {
305         /* No lights are defined... That means, lit vertices should be entirely black */
306         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
307         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
308         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
309                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
310         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
311
312         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
313         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
314         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
315                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
316         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
317
318         hr = IDirect3DDevice9_SetFVF(device, nfvf);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
320
321         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
322         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
323         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
324                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
325         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
326
327         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
328         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
329         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
330                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
331         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
332
333         IDirect3DDevice9_EndScene(device);
334         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
335     }
336
337     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
338
339     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
340     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
341     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
342     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
343     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
344     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
345     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
346     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
347
348     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
349     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
350     memset(&material, 0, sizeof(material));
351     material.Diffuse.r = 0.0;
352     material.Diffuse.g = 0.0;
353     material.Diffuse.b = 0.0;
354     material.Diffuse.a = 1.0;
355     material.Ambient.r = 0.0;
356     material.Ambient.g = 0.0;
357     material.Ambient.b = 0.0;
358     material.Ambient.a = 0.0;
359     material.Specular.r = 0.0;
360     material.Specular.g = 0.0;
361     material.Specular.b = 0.0;
362     material.Specular.a = 0.0;
363     material.Emissive.r = 0.0;
364     material.Emissive.g = 0.0;
365     material.Emissive.b = 0.0;
366     material.Emissive.a = 0.0;
367     material.Power = 0.0;
368     IDirect3DDevice9_SetMaterial(device, &material);
369     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
370
371     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
372     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
373     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
374     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
375
376     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
377     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
378     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
379     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
380     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
382     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
383     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
384
385     hr = IDirect3DDevice9_BeginScene(device);
386     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
387     if(SUCCEEDED(hr)) {
388         struct vertex lighting_test[] = {
389             {-1.0,   -1.0,   0.1,    0x8000ff00},
390             { 1.0,   -1.0,   0.1,    0x80000000},
391             {-1.0,    1.0,   0.1,    0x8000ff00},
392             { 1.0,    1.0,   0.1,    0x80000000}
393         };
394         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
395         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
396         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
397         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
398
399         hr = IDirect3DDevice9_EndScene(device);
400         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
401     }
402
403     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
404     color = getPixelColor(device, 320, 240);
405     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
406
407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
408     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
409     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
410     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
411     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
412     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
413     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
414     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
415     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
416     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
417     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
418     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
419 }
420
421 static void clear_test(IDirect3DDevice9 *device)
422 {
423     /* Tests the correctness of clearing parameters */
424     HRESULT hr;
425     D3DRECT rect[2];
426     D3DRECT rect_negneg;
427     DWORD color;
428     D3DVIEWPORT9 old_vp, vp;
429     RECT scissor;
430     DWORD oldColorWrite;
431     BOOL invalid_clear_failed = FALSE;
432
433     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
434     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
435
436     /* Positive x, negative y */
437     rect[0].x1 = 0;
438     rect[0].y1 = 480;
439     rect[0].x2 = 320;
440     rect[0].y2 = 240;
441
442     /* Positive x, positive y */
443     rect[1].x1 = 0;
444     rect[1].y1 = 0;
445     rect[1].x2 = 320;
446     rect[1].y2 = 240;
447     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
448      * returns D3D_OK, but ignores the rectangle silently
449      */
450     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
451     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
452     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
453
454     /* negative x, negative y */
455     rect_negneg.x1 = 640;
456     rect_negneg.y1 = 240;
457     rect_negneg.x2 = 320;
458     rect_negneg.y2 = 0;
459     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
460     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
461     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
462
463     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
464
465     color = getPixelColor(device, 160, 360); /* lower left quad */
466     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
467     color = getPixelColor(device, 160, 120); /* upper left quad */
468     if(invalid_clear_failed) {
469         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
470         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
471     } else {
472         /* If the negative rectangle was dropped silently, the correct ones are cleared */
473         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
474     }
475     color = getPixelColor(device, 480, 360); /* lower right quad  */
476     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
477     color = getPixelColor(device, 480, 120); /* upper right quad */
478     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
479
480     /* Test how the viewport affects clears */
481     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
482     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
483     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
484     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
485
486     vp.X = 160;
487     vp.Y = 120;
488     vp.Width = 160;
489     vp.Height = 120;
490     vp.MinZ = 0.0;
491     vp.MaxZ = 1.0;
492     hr = IDirect3DDevice9_SetViewport(device, &vp);
493     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
495     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
496
497     vp.X = 320;
498     vp.Y = 240;
499     vp.Width = 320;
500     vp.Height = 240;
501     vp.MinZ = 0.0;
502     vp.MaxZ = 1.0;
503     hr = IDirect3DDevice9_SetViewport(device, &vp);
504     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
505     rect[0].x1 = 160;
506     rect[0].y1 = 120;
507     rect[0].x2 = 480;
508     rect[0].y2 = 360;
509     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
510     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
511
512     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
513     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
514
515     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
516     color = getPixelColor(device, 158, 118);
517     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
518     color = getPixelColor(device, 162, 118);
519     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
520     color = getPixelColor(device, 158, 122);
521     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
522     color = getPixelColor(device, 162, 122);
523     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
524
525     color = getPixelColor(device, 318, 238);
526     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
527     color = getPixelColor(device, 322, 238);
528     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
529     color = getPixelColor(device, 318, 242);
530     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
531     color = getPixelColor(device, 322, 242);
532     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
533
534     color = getPixelColor(device, 478, 358);
535     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
536     color = getPixelColor(device, 482, 358);
537     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
538     color = getPixelColor(device, 478, 362);
539     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
540     color = getPixelColor(device, 482, 362);
541     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
542
543     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
544     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
545
546     scissor.left = 160;
547     scissor.right = 480;
548     scissor.top = 120;
549     scissor.bottom = 360;
550     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
551     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
552     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
553     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
554
555     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
556     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
557     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
558     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
559
560     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
561     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
562
563     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
564     color = getPixelColor(device, 158, 118);
565     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
566     color = getPixelColor(device, 162, 118);
567     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
568     color = getPixelColor(device, 158, 122);
569     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
570     color = getPixelColor(device, 162, 122);
571     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
572
573     color = getPixelColor(device, 158, 358);
574     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
575     color = getPixelColor(device, 162, 358);
576     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
577     color = getPixelColor(device, 158, 358);
578     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
579     color = getPixelColor(device, 162, 362);
580     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
581
582     color = getPixelColor(device, 478, 118);
583     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
584     color = getPixelColor(device, 478, 122);
585     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
586     color = getPixelColor(device, 482, 122);
587     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
588     color = getPixelColor(device, 482, 358);
589     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
590
591     color = getPixelColor(device, 478, 358);
592     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
593     color = getPixelColor(device, 478, 362);
594     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
595     color = getPixelColor(device, 482, 358);
596     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
597     color = getPixelColor(device, 482, 362);
598     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
599
600     color = getPixelColor(device, 318, 238);
601     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
602     color = getPixelColor(device, 318, 242);
603     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
604     color = getPixelColor(device, 322, 238);
605     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
606     color = getPixelColor(device, 322, 242);
607     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
608
609     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
610     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
611     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
612     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
613
614     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
615     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
616
617     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
618     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
619
620     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
621
622     /* Colorwriteenable does not affect the clear */
623     color = getPixelColor(device, 320, 240);
624     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
625 }
626
627 typedef struct {
628     float in[4];
629     DWORD out;
630 } test_data_t;
631
632 /*
633  *  c7      mova    ARGB            mov     ARGB
634  * -2.4     -2      0x00ffff00      -3      0x00ff0000
635  * -1.6     -2      0x00ffff00      -2      0x00ffff00
636  * -0.4      0      0x0000ffff      -1      0x0000ff00
637  *  0.4      0      0x0000ffff       0      0x0000ffff
638  *  1.6      2      0x00ff00ff       1      0x000000ff
639  *  2.4      2      0x00ff00ff       2      0x00ff00ff
640  */
641 static void test_mova(IDirect3DDevice9 *device)
642 {
643     static const DWORD mova_test[] = {
644         0xfffe0200,                                                             /* vs_2_0                       */
645         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
646         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
647         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
648         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
649         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
650         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
651         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
652         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
653         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
654         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
655         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
656         0x0000ffff                                                              /* END                          */
657     };
658     static const DWORD mov_test[] = {
659         0xfffe0101,                                                             /* vs_1_1                       */
660         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
661         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
662         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
663         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
664         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
665         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
666         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
667         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
668         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
669         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
670         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
671         0x0000ffff                                                              /* END                          */
672     };
673
674     static const test_data_t test_data[2][6] = {
675         {
676             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
677             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
678             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
679             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
680             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
681             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
682         },
683         {
684             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
685             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
686             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
687             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
688             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
689             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
690         }
691     };
692
693     static const float quad[][3] = {
694         {-1.0f, -1.0f, 0.0f},
695         {-1.0f,  1.0f, 0.0f},
696         { 1.0f, -1.0f, 0.0f},
697         { 1.0f,  1.0f, 0.0f},
698     };
699
700     static const D3DVERTEXELEMENT9 decl_elements[] = {
701         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
702         D3DDECL_END()
703     };
704
705     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
706     IDirect3DVertexShader9 *mova_shader = NULL;
707     IDirect3DVertexShader9 *mov_shader = NULL;
708     HRESULT hr;
709     UINT i, j;
710
711     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
712     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
713     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
714     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
715     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
716     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
717     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
718     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
719
720     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
721     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
722     for(j = 0; j < 2; ++j)
723     {
724         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
725         {
726             DWORD color;
727
728             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
729             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
730
731             hr = IDirect3DDevice9_BeginScene(device);
732             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
733
734             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
735             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
736
737             hr = IDirect3DDevice9_EndScene(device);
738             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
739
740             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
741             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
742
743             color = getPixelColor(device, 320, 240);
744             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
745                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
746
747             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
748             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
749         }
750         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
751         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
752     }
753
754     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
755     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
756
757     IDirect3DVertexDeclaration9_Release(vertex_declaration);
758     IDirect3DVertexShader9_Release(mova_shader);
759     IDirect3DVertexShader9_Release(mov_shader);
760 }
761
762 struct sVertex {
763     float x, y, z;
764     DWORD diffuse;
765     DWORD specular;
766 };
767
768 struct sVertexT {
769     float x, y, z, rhw;
770     DWORD diffuse;
771     DWORD specular;
772 };
773
774 static void fog_test(IDirect3DDevice9 *device)
775 {
776     HRESULT hr;
777     D3DCOLOR color;
778     float start = 0.0f, end = 1.0f;
779     D3DCAPS9 caps;
780     int i;
781
782     /* Gets full z based fog with linear fog, no fog with specular color */
783     struct sVertex unstransformed_1[] = {
784         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
785         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
786         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
787         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
788     };
789     /* Ok, I am too lazy to deal with transform matrices */
790     struct sVertex unstransformed_2[] = {
791         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
792         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
793         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
794         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
795     };
796     /* Untransformed ones. Give them a different diffuse color to make the test look
797      * nicer. It also makes making sure that they are drawn correctly easier.
798      */
799     struct sVertexT transformed_1[] = {
800         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
801         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
802         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
803         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
804     };
805     struct sVertexT transformed_2[] = {
806         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
807         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
808         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
809         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
810     };
811     struct vertex rev_fog_quads[] = {
812        {-1.0,   -1.0,   0.1,    0x000000ff},
813        {-1.0,    0.0,   0.1,    0x000000ff},
814        { 0.0,    0.0,   0.1,    0x000000ff},
815        { 0.0,   -1.0,   0.1,    0x000000ff},
816
817        { 0.0,   -1.0,   0.9,    0x000000ff},
818        { 0.0,    0.0,   0.9,    0x000000ff},
819        { 1.0,    0.0,   0.9,    0x000000ff},
820        { 1.0,   -1.0,   0.9,    0x000000ff},
821
822        { 0.0,    0.0,   0.4,    0x000000ff},
823        { 0.0,    1.0,   0.4,    0x000000ff},
824        { 1.0,    1.0,   0.4,    0x000000ff},
825        { 1.0,    0.0,   0.4,    0x000000ff},
826
827        {-1.0,    0.0,   0.7,    0x000000ff},
828        {-1.0,    1.0,   0.7,    0x000000ff},
829        { 0.0,    1.0,   0.7,    0x000000ff},
830        { 0.0,    0.0,   0.7,    0x000000ff},
831     };
832     WORD Indices[] = {0, 1, 2, 2, 3, 0};
833
834     memset(&caps, 0, sizeof(caps));
835     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
836     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
837     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
838     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
839
840     /* Setup initial states: No lighting, fog on, fog color */
841     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
842     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
843     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
844     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
845     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
846     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
847
848     /* First test: Both table fog and vertex fog off */
849     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
850     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
851     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
852     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
853
854     /* Start = 0, end = 1. Should be default, but set them */
855     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
856     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
857     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
858     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
859
860     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
861     {
862         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
863         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
864         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
865         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
866                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
867                                                      sizeof(unstransformed_1[0]));
868         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
869
870         /* That makes it use the Z value */
871         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
872         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
873         /* Untransformed, vertex fog != none (or table fog != none):
874          * Use the Z value as input into the equation
875          */
876         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
877                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
878                                                      sizeof(unstransformed_1[0]));
879         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
880
881         /* transformed verts */
882         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
883         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
884         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
885         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
886                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
887                                                      sizeof(transformed_1[0]));
888         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
889
890         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
891         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
892         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
893          * equation
894          */
895         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
896                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
897                                                      sizeof(transformed_2[0]));
898
899         hr = IDirect3DDevice9_EndScene(device);
900         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
901     }
902     else
903     {
904         ok(FALSE, "BeginScene failed\n");
905     }
906
907     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
908     color = getPixelColor(device, 160, 360);
909     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
910     color = getPixelColor(device, 160, 120);
911     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
912     color = getPixelColor(device, 480, 120);
913     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
914     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
915     {
916         color = getPixelColor(device, 480, 360);
917         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
918     }
919     else
920     {
921         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
922          * The settings above result in no fogging with vertex fog
923          */
924         color = getPixelColor(device, 480, 120);
925         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
926         trace("Info: Table fog not supported by this device\n");
927     }
928
929     /* Now test the special case fogstart == fogend */
930     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
931     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
932
933     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
934     {
935         start = 512;
936         end = 512;
937         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
938         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
939         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
940         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
941
942         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
943         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
944         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
945         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
946         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
948
949         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
950          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
951          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
952          * The third transformed quad remains unfogged because the fogcoords are read from the specular
953          * color and has fixed fogstart and fogend.
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
957                 sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
960                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
961                 sizeof(unstransformed_1[0]));
962         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
963
964         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
965         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
966         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
967         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
968                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
969                 sizeof(transformed_1[0]));
970         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
971
972         hr = IDirect3DDevice9_EndScene(device);
973         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
974     }
975     else
976     {
977         ok(FALSE, "BeginScene failed\n");
978     }
979     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
980     color = getPixelColor(device, 160, 360);
981     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
982     color = getPixelColor(device, 160, 120);
983     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
984     color = getPixelColor(device, 480, 120);
985     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
986
987     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
988      * but without shaders it seems to work everywhere
989      */
990     end = 0.2;
991     start = 0.8;
992     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
993     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
995     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
996     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
997     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
998
999     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1000      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1001      * so skip this for now
1002      */
1003     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1004         const char *mode = (i ? "table" : "vertex");
1005         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1006         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1007         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1008         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1009         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1010         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1011         hr = IDirect3DDevice9_BeginScene(device);
1012         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1013         if(SUCCEEDED(hr)) {
1014             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1015                                 4,  5,  6,  6,  7, 4,
1016                                 8,  9, 10, 10, 11, 8,
1017                             12, 13, 14, 14, 15, 12};
1018
1019             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1020                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1021                     sizeof(rev_fog_quads[0]));
1022
1023             hr = IDirect3DDevice9_EndScene(device);
1024             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1025         }
1026         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1027         color = getPixelColor(device, 160, 360);
1028         ok(color_match(color, 0x0000ff00, 1),
1029                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1030
1031         color = getPixelColor(device, 160, 120);
1032         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1033                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1034
1035         color = getPixelColor(device, 480, 120);
1036         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1037                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1038
1039         color = getPixelColor(device, 480, 360);
1040         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1041
1042         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1043             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1044             break;
1045         }
1046     }
1047     /* Turn off the fog master switch to avoid confusing other tests */
1048     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1049     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1050     start = 0.0;
1051     end = 1.0;
1052     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1053     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1054     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1055     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1057     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1059     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1060 }
1061
1062 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1063  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1064  * regardless of the actual addressing mode set. */
1065 static void test_cube_wrap(IDirect3DDevice9 *device)
1066 {
1067     static const float quad[][6] = {
1068         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1069         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1070         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1071         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1072     };
1073
1074     static const D3DVERTEXELEMENT9 decl_elements[] = {
1075         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1076         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1077         D3DDECL_END()
1078     };
1079
1080     static const struct {
1081         D3DTEXTUREADDRESS mode;
1082         const char *name;
1083     } address_modes[] = {
1084         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1085         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1086         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1087         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1088         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1089     };
1090
1091     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1092     IDirect3DCubeTexture9 *texture = NULL;
1093     IDirect3DSurface9 *surface = NULL;
1094     D3DLOCKED_RECT locked_rect;
1095     HRESULT hr;
1096     UINT x;
1097     INT y, face;
1098
1099     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1100     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1101     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1102     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1103
1104     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1105             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1106     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1107
1108     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1109     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1110
1111     for (y = 0; y < 128; ++y)
1112     {
1113         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1114         for (x = 0; x < 64; ++x)
1115         {
1116             *ptr++ = 0xffff0000;
1117         }
1118         for (x = 64; x < 128; ++x)
1119         {
1120             *ptr++ = 0xff0000ff;
1121         }
1122     }
1123
1124     hr = IDirect3DSurface9_UnlockRect(surface);
1125     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1126
1127     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1128             D3DPOOL_DEFAULT, &texture, NULL);
1129     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1130
1131     /* Create cube faces */
1132     for (face = 0; face < 6; ++face)
1133     {
1134         IDirect3DSurface9 *face_surface = NULL;
1135
1136         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1137         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1138
1139         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1140         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1141
1142         IDirect3DSurface9_Release(face_surface);
1143     }
1144
1145     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1146     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1147
1148     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1149     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1150     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1151     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1152     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1153     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1154
1155     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1156     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1157
1158     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1159     {
1160         DWORD color;
1161
1162         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1163         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1164         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1165         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1166
1167         hr = IDirect3DDevice9_BeginScene(device);
1168         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1169
1170         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1171         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1172
1173         hr = IDirect3DDevice9_EndScene(device);
1174         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1175
1176         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1177         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1178
1179         /* Due to the nature of this test, we sample essentially at the edge
1180          * between two faces. Because of this it's undefined from which face
1181          * the driver will sample. Fortunately that's not important for this
1182          * test, since all we care about is that it doesn't sample from the
1183          * other side of the surface or from the border. */
1184         color = getPixelColor(device, 320, 240);
1185         ok(color == 0x00ff0000 || color == 0x000000ff,
1186                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1187                 color, address_modes[x].name);
1188
1189         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1190         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1191     }
1192
1193     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1194     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1195
1196     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1197     IDirect3DCubeTexture9_Release(texture);
1198     IDirect3DSurface9_Release(surface);
1199 }
1200
1201 static void offscreen_test(IDirect3DDevice9 *device)
1202 {
1203     HRESULT hr;
1204     IDirect3DTexture9 *offscreenTexture = NULL;
1205     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1206     DWORD color;
1207
1208     static const float quad[][5] = {
1209         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1210         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1211         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1212         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1213     };
1214
1215     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1216     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1217
1218     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1219     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1220     if(!offscreenTexture) {
1221         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1222         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, 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             skip("Cannot create an offscreen render target\n");
1226             goto out;
1227         }
1228     }
1229
1230     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1231     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1232     if(!backbuffer) {
1233         goto out;
1234     }
1235
1236     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1237     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1238     if(!offscreen) {
1239         goto out;
1240     }
1241
1242     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1243     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1244
1245     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1246     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1247     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1248     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1249     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1250     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1251     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1252     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1253     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1254     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1255
1256     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1257         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1258         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1259         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1260         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1261
1262         /* Draw without textures - Should result in a white quad */
1263         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1264         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1265
1266         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1267         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1268         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1269         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1270
1271         /* This time with the texture */
1272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1273         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1274
1275         IDirect3DDevice9_EndScene(device);
1276     }
1277
1278     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1279
1280     /* Center quad - should be white */
1281     color = getPixelColor(device, 320, 240);
1282     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1283     /* Some quad in the cleared part of the texture */
1284     color = getPixelColor(device, 170, 240);
1285     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1286     /* Part of the originally cleared back buffer */
1287     color = getPixelColor(device, 10, 10);
1288     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1289     if(0) {
1290         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1291          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1292          * the offscreen rendering mode this test would succeed or fail
1293          */
1294         color = getPixelColor(device, 10, 470);
1295         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1296     }
1297
1298 out:
1299     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1300
1301     /* restore things */
1302     if(backbuffer) {
1303         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1304         IDirect3DSurface9_Release(backbuffer);
1305     }
1306     if(offscreenTexture) {
1307         IDirect3DTexture9_Release(offscreenTexture);
1308     }
1309     if(offscreen) {
1310         IDirect3DSurface9_Release(offscreen);
1311     }
1312 }
1313
1314 /* This test tests fog in combination with shaders.
1315  * What's tested: linear fog (vertex and table) with pixel shader
1316  *                linear table fog with non foggy vertex shader
1317  *                vertex fog with foggy vertex shader, non-linear
1318  *                fog with shader, non-linear fog with foggy shader,
1319  *                linear table fog with foggy shader
1320  */
1321 static void fog_with_shader_test(IDirect3DDevice9 *device)
1322 {
1323     HRESULT hr;
1324     DWORD color;
1325     union {
1326         float f;
1327         DWORD i;
1328     } start, end;
1329     unsigned int i, j;
1330
1331     /* basic vertex shader without fog computation ("non foggy") */
1332     static const DWORD vertex_shader_code1[] = {
1333         0xfffe0101,                                                             /* vs_1_1                       */
1334         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1335         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1336         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1337         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1338         0x0000ffff
1339     };
1340     /* basic vertex shader with reversed fog computation ("foggy") */
1341     static const DWORD vertex_shader_code2[] = {
1342         0xfffe0101,                                                             /* vs_1_1                        */
1343         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1344         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1345         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1346         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1347         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1348         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1349         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1350         0x0000ffff
1351     };
1352     /* basic pixel shader */
1353     static const DWORD pixel_shader_code[] = {
1354         0xffff0101,                                                             /* ps_1_1     */
1355         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1356         0x0000ffff
1357     };
1358
1359     static struct vertex quad[] = {
1360         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1361         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1362         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1363         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1364     };
1365
1366     static const D3DVERTEXELEMENT9 decl_elements[] = {
1367         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1368         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1369         D3DDECL_END()
1370     };
1371
1372     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1373     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1374     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1375
1376     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1377     static const struct test_data_t {
1378         int vshader;
1379         int pshader;
1380         D3DFOGMODE vfog;
1381         D3DFOGMODE tfog;
1382         unsigned int color[11];
1383     } test_data[] = {
1384         /* only pixel shader: */
1385         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1386         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1387         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1388         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1389         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1390         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1391         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1392         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1395         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1398         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400
1401         /* vertex shader */
1402         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1403         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1404          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1405         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1406         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1407         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1408         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1409         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1410         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1411
1412         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1413         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1414         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1415         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1416         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1417         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418
1419         /* vertex shader and pixel shader */
1420         /* The next 4 tests would read the fog coord output, but it isn't available.
1421          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1422          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1423          * These tests should be disabled if some other hardware behaves differently
1424          */
1425         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1426         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1427         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1428         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1429         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1430         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1431         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1432         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1433         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1434         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1435         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1436         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1437
1438         /* These use the Z coordinate with linear table fog */
1439         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1440         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1441         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1442         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1443         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1444         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1445         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1446         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1447         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1448         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1449         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1450         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1451
1452         /* Non-linear table fog without fog coord */
1453         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1454         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1455         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1456         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1457         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1458         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1459
1460 #if 0  /* FIXME: these fail on GeForce 8500 */
1461         /* foggy vertex shader */
1462         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1463         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1464          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1465         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1466         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1467          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1468         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1469         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1470          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1471         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1472         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1473          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1474 #endif
1475
1476         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1477          * all using the fixed fog-coord linear fog
1478          */
1479         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1480         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1481          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1482         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1483         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1484          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1485         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1486         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1487          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1488         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1489         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1490          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1491
1492         /* These use table fog. Here the shader-provided fog coordinate is
1493          * ignored and the z coordinate used instead
1494          */
1495         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1496         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1497         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1498         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1499         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1500         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1501         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1502         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1503         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1504     };
1505
1506     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1507     start.f=0.1f;
1508     end.f=0.9f;
1509
1510     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1511     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1512     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1513     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1514     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1515     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1516     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1517     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1518
1519     /* Setup initial states: No lighting, fog on, fog color */
1520     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1521     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1522     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1523     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1524     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1525     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1526     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1527     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1528
1529     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1530     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1531     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1532     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1533
1534     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1535     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1536     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1537     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1538     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1539
1540     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1541     {
1542         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1543         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1544         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1545         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1546         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1547         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1548         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1549         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1550
1551         for(j=0; j < 11; j++)
1552         {
1553             /* Don't use the whole zrange to prevent rounding errors */
1554             quad[0].z = 0.001f + (float)j / 10.02f;
1555             quad[1].z = 0.001f + (float)j / 10.02f;
1556             quad[2].z = 0.001f + (float)j / 10.02f;
1557             quad[3].z = 0.001f + (float)j / 10.02f;
1558
1559             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1560             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1561
1562             hr = IDirect3DDevice9_BeginScene(device);
1563             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1564
1565             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1566             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1567
1568             hr = IDirect3DDevice9_EndScene(device);
1569             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1570
1571             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1572
1573             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1574             color = getPixelColor(device, 128, 240);
1575             ok(color_match(color, test_data[i].color[j], 13),
1576                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1577                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1578         }
1579     }
1580
1581     /* reset states */
1582     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1583     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1584     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1585     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1586     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1587     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1588     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1589     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1590
1591     IDirect3DVertexShader9_Release(vertex_shader[1]);
1592     IDirect3DVertexShader9_Release(vertex_shader[2]);
1593     IDirect3DPixelShader9_Release(pixel_shader[1]);
1594     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1595 }
1596
1597 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1598     unsigned int i, x, y;
1599     HRESULT hr;
1600     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1601     D3DLOCKED_RECT locked_rect;
1602
1603     /* Generate the textures */
1604     for(i=0; i<2; i++)
1605     {
1606         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1607                                             D3DPOOL_MANAGED, &texture[i], NULL);
1608         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1609
1610         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1611         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1612         for (y = 0; y < 128; ++y)
1613         {
1614             if(i)
1615             { /* Set up black texture with 2x2 texel white spot in the middle */
1616                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1617                 for (x = 0; x < 128; ++x)
1618                 {
1619                     if(y>62 && y<66 && x>62 && x<66)
1620                         *ptr++ = 0xffffffff;
1621                     else
1622                         *ptr++ = 0xff000000;
1623                 }
1624             }
1625             else
1626             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1627                * (if multiplied with bumpenvmat)
1628               */
1629                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1630                 for (x = 0; x < 128; ++x)
1631                 {
1632                     if(abs(x-64)>abs(y-64))
1633                     {
1634                         if(x < 64)
1635                             *ptr++ = 0xc000;
1636                         else
1637                             *ptr++ = 0x4000;
1638                     }
1639                     else
1640                     {
1641                         if(y < 64)
1642                             *ptr++ = 0x0040;
1643                         else
1644                             *ptr++ = 0x00c0;
1645                     }
1646                 }
1647             }
1648         }
1649         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1650         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1651
1652         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1653         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1654
1655         /* Disable texture filtering */
1656         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1657         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1659         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1660
1661         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1662         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1663         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1664         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1665     }
1666 }
1667
1668 /* test the behavior of the texbem instruction
1669  * with normal 2D and projective 2D textures
1670  */
1671 static void texbem_test(IDirect3DDevice9 *device)
1672 {
1673     HRESULT hr;
1674     DWORD color;
1675     int i;
1676
1677     static const DWORD pixel_shader_code[] = {
1678         0xffff0101,                         /* ps_1_1*/
1679         0x00000042, 0xb00f0000,             /* tex t0*/
1680         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1681         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1682         0x0000ffff
1683     };
1684     static const DWORD double_texbem_code[] =  {
1685         0xffff0103,                                         /* ps_1_3           */
1686         0x00000042, 0xb00f0000,                             /* tex t0           */
1687         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1688         0x00000042, 0xb00f0002,                             /* tex t2           */
1689         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1690         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1691         0x0000ffff                                          /* end              */
1692     };
1693
1694
1695     static const float quad[][7] = {
1696         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1697         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1698         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1699         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1700     };
1701     static const float quad_proj[][9] = {
1702         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1703         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1704         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1705         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1706     };
1707
1708     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1709         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1710         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1711         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1712         D3DDECL_END()
1713     },{
1714         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1715         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1716         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1717         D3DDECL_END()
1718     } };
1719
1720     /* use asymmetric matrix to test loading */
1721     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1722
1723     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1724     IDirect3DPixelShader9       *pixel_shader       = NULL;
1725     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1726     D3DLOCKED_RECT locked_rect;
1727
1728     generate_bumpmap_textures(device);
1729
1730     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1731     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1732     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1733     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1734     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1735
1736     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1737     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1738
1739     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1740     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1741
1742     for(i=0; i<2; i++)
1743     {
1744         if(i)
1745         {
1746             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1747             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1748         }
1749
1750         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1751         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1752         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1753         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1754
1755         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1756         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1757         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1758         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1759
1760         hr = IDirect3DDevice9_BeginScene(device);
1761         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1762
1763         if(!i)
1764             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1765         else
1766             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1767         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1768
1769         hr = IDirect3DDevice9_EndScene(device);
1770         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1771
1772         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1773         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1774
1775         color = getPixelColor(device, 320-32, 240);
1776         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1777         color = getPixelColor(device, 320+32, 240);
1778         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1779         color = getPixelColor(device, 320, 240-32);
1780         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1781         color = getPixelColor(device, 320, 240+32);
1782         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1783
1784         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1785         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1786         IDirect3DPixelShader9_Release(pixel_shader);
1787
1788         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1789         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1790         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1791     }
1792
1793     /* clean up */
1794     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1795     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1796
1797     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1798     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1799
1800     for(i=0; i<2; i++)
1801     {
1802         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1803         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1804         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1805         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1806         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1807         IDirect3DTexture9_Release(texture);
1808     }
1809
1810     /* Test double texbem */
1811     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1812     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1813     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1814     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1815     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1816     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1817     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1818     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1819
1820     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1821     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1822     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1823     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1824
1825     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1826     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1827
1828     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1829     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1830     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1831     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1832     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1833     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1834
1835     {
1836         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1837 #define tex  0x00ff0000
1838 #define tex1 0x0000ff00
1839 #define origin 0x000000ff
1840         static const DWORD pixel_data[] = {
1841             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1842             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1843             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1844             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1845             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1846             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1847             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1848             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1849         };
1850 #undef tex1
1851 #undef tex2
1852 #undef origin
1853
1854         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1855         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1856         for(i = 0; i < 8; i++) {
1857             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1858         }
1859         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1860         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1861     }
1862
1863     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1864     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1865     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1866     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1867     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1868     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1869     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1870     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1871     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1872     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1873     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1874     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1875
1876     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1877     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1878     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1879     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1880     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1881     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1882
1883     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1884     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1885     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1886     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1887     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1888     IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1889
1890     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1891     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1892     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1893     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1894     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1895     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1896     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1897     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1898
1899     hr = IDirect3DDevice9_BeginScene(device);
1900     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1901     if(SUCCEEDED(hr)) {
1902         static const float double_quad[] = {
1903             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1904              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1905             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1906              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1907         };
1908
1909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1910         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1911         hr = IDirect3DDevice9_EndScene(device);
1912         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1913     }
1914     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1915     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1916     color = getPixelColor(device, 320, 240);
1917     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1918
1919     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1920     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1921     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1922     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1923     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1928     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1929
1930     IDirect3DPixelShader9_Release(pixel_shader);
1931     IDirect3DTexture9_Release(texture);
1932     IDirect3DTexture9_Release(texture1);
1933     IDirect3DTexture9_Release(texture2);
1934 }
1935
1936 static void z_range_test(IDirect3DDevice9 *device)
1937 {
1938     const struct vertex quad[] =
1939     {
1940         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1941         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1942         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1943         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1944     };
1945     const struct vertex quad2[] =
1946     {
1947         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1948         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1949         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1950         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1951     };
1952
1953     const struct tvertex quad3[] =
1954     {
1955         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1956         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1957         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1958         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1959     };
1960     const struct tvertex quad4[] =
1961     {
1962         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
1963         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
1964         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
1965         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
1966     };
1967     HRESULT hr;
1968     DWORD color;
1969     IDirect3DVertexShader9 *shader;
1970     IDirect3DVertexDeclaration9 *decl;
1971     D3DCAPS9 caps;
1972     const DWORD shader_code[] = {
1973         0xfffe0101,                                     /* vs_1_1           */
1974         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
1975         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
1976         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
1977         0x0000ffff                                      /* end              */
1978     };
1979     static const D3DVERTEXELEMENT9 decl_elements[] = {
1980         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1981         D3DDECL_END()
1982     };
1983     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1984      * then call Present. Then clear the color buffer to make sure it has some defined content
1985      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1986      * by the depth value.
1987      */
1988     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1989     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1990     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1991     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1992
1993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1994     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1995     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1996     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1997     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1998     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1999     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2000     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2001     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2002     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2003
2004     hr = IDirect3DDevice9_BeginScene(device);
2005     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2006     if(hr == D3D_OK)
2007     {
2008         /* Test the untransformed vertex path */
2009         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2010         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2011         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2012         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2013         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2014         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2015
2016         /* Test the transformed vertex path */
2017         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2018         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2019
2020         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2021         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2022         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2023         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2024         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2025         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2026
2027         hr = IDirect3DDevice9_EndScene(device);
2028         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2029     }
2030
2031     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2032     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2033
2034     /* Do not test the exact corner pixels, but go pretty close to them */
2035
2036     /* Clipped because z > 1.0 */
2037     color = getPixelColor(device, 28, 238);
2038     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2039     color = getPixelColor(device, 28, 241);
2040     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2041
2042     /* Not clipped, > z buffer clear value(0.75) */
2043     color = getPixelColor(device, 31, 238);
2044     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2045     color = getPixelColor(device, 31, 241);
2046     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2047     color = getPixelColor(device, 100, 238);
2048     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2049     color = getPixelColor(device, 100, 241);
2050     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2051
2052     /* Not clipped, < z buffer clear value */
2053     color = getPixelColor(device, 104, 238);
2054     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2055     color = getPixelColor(device, 104, 241);
2056     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2057     color = getPixelColor(device, 318, 238);
2058     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2059     color = getPixelColor(device, 318, 241);
2060     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2061
2062     /* Clipped because z < 0.0 */
2063     color = getPixelColor(device, 321, 238);
2064     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2065     color = getPixelColor(device, 321, 241);
2066     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2067
2068     /* Test the shader path */
2069     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2070     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2071         skip("Vertex shaders not supported\n");
2072         goto out;
2073     }
2074     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2075     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2076     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2077     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2078
2079     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2080
2081     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2082     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2083     IDirect3DDevice9_SetVertexShader(device, shader);
2084     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2085
2086     hr = IDirect3DDevice9_BeginScene(device);
2087     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2088     if(hr == D3D_OK)
2089     {
2090         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2091         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2092         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2093         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2094         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2095         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2096         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2097         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2098         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2099         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2100
2101         hr = IDirect3DDevice9_EndScene(device);
2102         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2103     }
2104
2105     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2106     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2107     IDirect3DDevice9_SetVertexShader(device, NULL);
2108     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2109
2110     IDirect3DVertexDeclaration9_Release(decl);
2111     IDirect3DVertexShader9_Release(shader);
2112
2113     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2114     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2115     /* Z < 1.0 */
2116     color = getPixelColor(device, 28, 238);
2117     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2118
2119     /* 1.0 < z < 0.75 */
2120     color = getPixelColor(device, 31, 238);
2121     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2122     color = getPixelColor(device, 100, 238);
2123     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2124
2125     /* 0.75 < z < 0.0 */
2126     color = getPixelColor(device, 104, 238);
2127     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2128     color = getPixelColor(device, 318, 238);
2129     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2130
2131     /* 0.0 < z */
2132     color = getPixelColor(device, 321, 238);
2133     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2134
2135     out:
2136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2137     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2139     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2141     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2142 }
2143
2144 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2145 {
2146     D3DSURFACE_DESC desc;
2147     D3DLOCKED_RECT l;
2148     HRESULT hr;
2149     unsigned int x, y;
2150     DWORD *mem;
2151
2152     memset(&desc, 0, sizeof(desc));
2153     memset(&l, 0, sizeof(l));
2154     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2155     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2156     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2157     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2158     if(FAILED(hr)) return;
2159
2160     for(y = 0; y < desc.Height; y++)
2161     {
2162         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2163         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2164         {
2165             mem[x] = color;
2166         }
2167     }
2168     hr = IDirect3DSurface9_UnlockRect(surface);
2169     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2170 }
2171
2172 /* This tests a variety of possible StretchRect() situations */
2173 static void stretchrect_test(IDirect3DDevice9 *device)
2174 {
2175     HRESULT hr;
2176     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2177     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2178     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2179     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2180     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2181     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2182     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2183     IDirect3DSurface9 *orig_rt = NULL;
2184     DWORD color;
2185
2186     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2187     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2188     if(!orig_rt) {
2189         goto out;
2190     }
2191
2192     /* Create our temporary surfaces in system memory */
2193     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2194     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2195     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2196     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2197
2198     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2199     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2200     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2201     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2203     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2205
2206     /* Create render target surfaces */
2207     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2208     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2209     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2210     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2211     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2212     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2213
2214     /* Create render target textures */
2215     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2216     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2217     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2218     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2219     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2220     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2221     if (tex_rt32) {
2222         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2223         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2224     }
2225     if (tex_rt64) {
2226         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2227         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2228     }
2229     if (tex_rt_dest64) {
2230         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2231         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2232     }
2233
2234     /* Create regular textures in D3DPOOL_DEFAULT */
2235     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2236     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2237     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2238     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2239     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2240     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2241     if (tex32) {
2242         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2243         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2244     }
2245     if (tex64) {
2246         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2247         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2248     }
2249     if (tex_dest64) {
2250         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2251         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2252     }
2253
2254     /*********************************************************************
2255      * Tests for when the source parameter is an offscreen plain surface *
2256      *********************************************************************/
2257
2258     /* Fill the offscreen 64x64 surface with green */
2259     if (surf_offscreen64)
2260         fill_surface(surf_offscreen64, 0xff00ff00);
2261
2262     /* offscreenplain ==> offscreenplain, same size */
2263     if(surf_offscreen64 && surf_offscreen_dest64) {
2264         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2265         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2266
2267         if (hr == D3D_OK) {
2268             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2269             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2270         }
2271     }
2272
2273     /* offscreenplain ==> rendertarget texture, same size */
2274     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2275         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2276         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2277
2278         /* We can't lock rendertarget textures, so copy to our temp surface first */
2279         if (hr == D3D_OK) {
2280             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2281             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2282         }
2283
2284         if (hr == D3D_OK) {
2285             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2286             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2287         }
2288     }
2289
2290     /* offscreenplain ==> rendertarget surface, same size */
2291     if(surf_offscreen64 && surf_rt_dest64) {
2292         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2293         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2294
2295         if (hr == D3D_OK) {
2296             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2297             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2298         }
2299     }
2300
2301     /* offscreenplain ==> texture, same size (should fail) */
2302     if(surf_offscreen64 && surf_tex_dest64) {
2303         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2304         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2305     }
2306
2307     /* Fill the smaller offscreen surface with red */
2308     fill_surface(surf_offscreen32, 0xffff0000);
2309
2310     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2311     if(surf_offscreen32 && surf_offscreen64) {
2312         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2313         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2314     }
2315
2316     /* offscreenplain ==> rendertarget texture, scaling */
2317     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2318         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2319         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2320
2321         /* We can't lock rendertarget textures, so copy to our temp surface first */
2322         if (hr == D3D_OK) {
2323             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2324             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2325         }
2326
2327         if (hr == D3D_OK) {
2328             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2329             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2330         }
2331     }
2332
2333     /* offscreenplain ==> rendertarget surface, scaling */
2334     if(surf_offscreen32 && surf_rt_dest64) {
2335         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2336         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2337
2338         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2339         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2340     }
2341
2342     /* offscreenplain ==> texture, scaling (should fail) */
2343     if(surf_offscreen32 && surf_tex_dest64) {
2344         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2345         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2346     }
2347
2348     /************************************************************
2349      * Tests for when the source parameter is a regular texture *
2350      ************************************************************/
2351
2352     /* Fill the surface of the regular texture with blue */
2353     if (surf_tex64 && surf_temp64) {
2354         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2355         fill_surface(surf_temp64, 0xff0000ff);
2356         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2357         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2358     }
2359
2360     /* texture ==> offscreenplain, same size */
2361     if(surf_tex64 && surf_offscreen64) {
2362         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2363         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2364     }
2365
2366     /* texture ==> rendertarget texture, same size */
2367     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2368         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2369         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2370
2371         /* We can't lock rendertarget textures, so copy to our temp surface first */
2372         if (hr == D3D_OK) {
2373             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2374             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2375         }
2376
2377         if (hr == D3D_OK) {
2378             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2379             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2380         }
2381     }
2382
2383     /* texture ==> rendertarget surface, same size */
2384     if(surf_tex64 && surf_rt_dest64) {
2385         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2386         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2387
2388         if (hr == D3D_OK) {
2389             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2390             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2391         }
2392     }
2393
2394     /* texture ==> texture, same size (should fail) */
2395     if(surf_tex64 && surf_tex_dest64) {
2396         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2397         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2398     }
2399
2400     /* Fill the surface of the smaller regular texture with red */
2401     if (surf_tex32 && surf_temp32) {
2402         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2403         fill_surface(surf_temp32, 0xffff0000);
2404         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2405         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2406     }
2407
2408     /* texture ==> offscreenplain, scaling (should fail) */
2409     if(surf_tex32 && surf_offscreen64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2411         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2412     }
2413
2414     /* texture ==> rendertarget texture, scaling */
2415     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2416         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2417         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2418
2419         /* We can't lock rendertarget textures, so copy to our temp surface first */
2420         if (hr == D3D_OK) {
2421             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2422             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2423         }
2424
2425         if (hr == D3D_OK) {
2426             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2427             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2428         }
2429     }
2430
2431     /* texture ==> rendertarget surface, scaling */
2432     if(surf_tex32 && surf_rt_dest64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2437         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2438     }
2439
2440     /* texture ==> texture, scaling (should fail) */
2441     if(surf_tex32 && surf_tex_dest64) {
2442         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2443         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2444     }
2445
2446     /*****************************************************************
2447      * Tests for when the source parameter is a rendertarget texture *
2448      *****************************************************************/
2449
2450     /* Fill the surface of the rendertarget texture with white */
2451     if (surf_tex_rt64 && surf_temp64) {
2452         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2453         fill_surface(surf_temp64, 0xffffffff);
2454         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2455         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2456     }
2457
2458     /* rendertarget texture ==> offscreenplain, same size */
2459     if(surf_tex_rt64 && surf_offscreen64) {
2460         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2461         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2462     }
2463
2464     /* rendertarget texture ==> rendertarget texture, same size */
2465     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2466         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2467         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2468
2469         /* We can't lock rendertarget textures, so copy to our temp surface first */
2470         if (hr == D3D_OK) {
2471             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2472             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2473         }
2474
2475         if (hr == D3D_OK) {
2476             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2477             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2478         }
2479     }
2480
2481     /* rendertarget texture ==> rendertarget surface, same size */
2482     if(surf_tex_rt64 && surf_rt_dest64) {
2483         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2484         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2485
2486         if (hr == D3D_OK) {
2487             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2488             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2489         }
2490     }
2491
2492     /* rendertarget texture ==> texture, same size (should fail) */
2493     if(surf_tex_rt64 && surf_tex_dest64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* Fill the surface of the smaller rendertarget texture with red */
2499     if (surf_tex_rt32 && surf_temp32) {
2500         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2501         fill_surface(surf_temp32, 0xffff0000);
2502         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2503         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2504     }
2505
2506     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2507     if(surf_tex_rt32 && surf_offscreen64) {
2508         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2509         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2510     }
2511
2512     /* rendertarget texture ==> rendertarget texture, scaling */
2513     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2514         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2515         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2516
2517         /* We can't lock rendertarget textures, so copy to our temp surface first */
2518         if (hr == D3D_OK) {
2519             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2520             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2521         }
2522
2523         if (hr == D3D_OK) {
2524             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2525             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2526         }
2527     }
2528
2529     /* rendertarget texture ==> rendertarget surface, scaling */
2530     if(surf_tex_rt32 && surf_rt_dest64) {
2531         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2532         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2533
2534         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2535         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2536     }
2537
2538     /* rendertarget texture ==> texture, scaling (should fail) */
2539     if(surf_tex_rt32 && surf_tex_dest64) {
2540         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2541         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2542     }
2543
2544     /*****************************************************************
2545      * Tests for when the source parameter is a rendertarget surface *
2546      *****************************************************************/
2547
2548     /* Fill the surface of the rendertarget surface with black */
2549     if (surf_rt64)
2550         fill_surface(surf_rt64, 0xff000000);
2551
2552     /* rendertarget texture ==> offscreenplain, same size */
2553     if(surf_rt64 && surf_offscreen64) {
2554         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2555         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2556     }
2557
2558     /* rendertarget surface ==> rendertarget texture, same size */
2559     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2560         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2561         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2562
2563         /* We can't lock rendertarget textures, so copy to our temp surface first */
2564         if (hr == D3D_OK) {
2565             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2566             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2567         }
2568
2569         if (hr == D3D_OK) {
2570             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2571             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2572         }
2573     }
2574
2575     /* rendertarget surface ==> rendertarget surface, same size */
2576     if(surf_rt64 && surf_rt_dest64) {
2577         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2578         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2579
2580         if (hr == D3D_OK) {
2581             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2582             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2583         }
2584     }
2585
2586     /* rendertarget surface ==> texture, same size (should fail) */
2587     if(surf_rt64 && surf_tex_dest64) {
2588         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2589         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2590     }
2591
2592     /* Fill the surface of the smaller rendertarget texture with red */
2593     if (surf_rt32)
2594         fill_surface(surf_rt32, 0xffff0000);
2595
2596     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2597     if(surf_rt32 && surf_offscreen64) {
2598         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2599         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2600     }
2601
2602     /* rendertarget surface ==> rendertarget texture, scaling */
2603     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2604         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2605         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2606
2607         /* We can't lock rendertarget textures, so copy to our temp surface first */
2608         if (hr == D3D_OK) {
2609             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2610             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2611         }
2612
2613         if (hr == D3D_OK) {
2614             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2615             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2616         }
2617     }
2618
2619     /* rendertarget surface ==> rendertarget surface, scaling */
2620     if(surf_rt32 && surf_rt_dest64) {
2621         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2622         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2623
2624         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2625         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2626     }
2627
2628     /* rendertarget surface ==> texture, scaling (should fail) */
2629     if(surf_rt32 && surf_tex_dest64) {
2630         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2631         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2632     }
2633
2634     /* TODO: Test when source and destination RECT parameters are given... */
2635     /* TODO: Test format conversions */
2636
2637
2638 out:
2639     /* Clean up */
2640     if (surf_rt32)
2641         IDirect3DSurface9_Release(surf_rt32);
2642     if (surf_rt64)
2643         IDirect3DSurface9_Release(surf_rt64);
2644     if (surf_rt_dest64)
2645         IDirect3DSurface9_Release(surf_rt_dest64);
2646     if (surf_temp32)
2647         IDirect3DSurface9_Release(surf_temp32);
2648     if (surf_temp64)
2649         IDirect3DSurface9_Release(surf_temp64);
2650     if (surf_offscreen32)
2651         IDirect3DSurface9_Release(surf_offscreen32);
2652     if (surf_offscreen64)
2653         IDirect3DSurface9_Release(surf_offscreen64);
2654     if (surf_offscreen_dest64)
2655         IDirect3DSurface9_Release(surf_offscreen_dest64);
2656
2657     if (tex_rt32) {
2658         if (surf_tex_rt32)
2659             IDirect3DSurface9_Release(surf_tex_rt32);
2660         IDirect3DTexture9_Release(tex_rt32);
2661     }
2662     if (tex_rt64) {
2663         if (surf_tex_rt64)
2664             IDirect3DSurface9_Release(surf_tex_rt64);
2665         IDirect3DTexture9_Release(tex_rt64);
2666     }
2667     if (tex_rt_dest64) {
2668         if (surf_tex_rt_dest64)
2669             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2670         IDirect3DTexture9_Release(tex_rt_dest64);
2671     }
2672     if (tex32) {
2673         if (surf_tex32)
2674             IDirect3DSurface9_Release(surf_tex32);
2675         IDirect3DTexture9_Release(tex32);
2676     }
2677     if (tex64) {
2678         if (surf_tex64)
2679             IDirect3DSurface9_Release(surf_tex64);
2680         IDirect3DTexture9_Release(tex64);
2681     }
2682     if (tex_dest64) {
2683         if (surf_tex_dest64)
2684             IDirect3DSurface9_Release(surf_tex_dest64);
2685         IDirect3DTexture9_Release(tex_dest64);
2686     }
2687
2688     if (orig_rt) {
2689         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2690         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2691         IDirect3DSurface9_Release(orig_rt);
2692     }
2693 }
2694
2695 static void maxmip_test(IDirect3DDevice9 *device)
2696 {
2697     IDirect3DTexture9 *texture = NULL;
2698     IDirect3DSurface9 *surface = NULL;
2699     HRESULT hr;
2700     DWORD color;
2701     const float quads[] = {
2702         -1.0,   -1.0,   0.0,    0.0,    0.0,
2703         -1.0,    0.0,   0.0,    0.0,    1.0,
2704          0.0,   -1.0,   0.0,    1.0,    0.0,
2705          0.0,    0.0,   0.0,    1.0,    1.0,
2706
2707          0.0,   -1.0,   0.0,    0.0,    0.0,
2708          0.0,    0.0,   0.0,    0.0,    1.0,
2709          1.0,   -1.0,   0.0,    1.0,    0.0,
2710          1.0,    0.0,   0.0,    1.0,    1.0,
2711
2712          0.0,    0.0,   0.0,    0.0,    0.0,
2713          0.0,    1.0,   0.0,    0.0,    1.0,
2714          1.0,    0.0,   0.0,    1.0,    0.0,
2715          1.0,    1.0,   0.0,    1.0,    1.0,
2716
2717         -1.0,    0.0,   0.0,    0.0,    0.0,
2718         -1.0,    1.0,   0.0,    0.0,    1.0,
2719          0.0,    0.0,   0.0,    1.0,    0.0,
2720          0.0,    1.0,   0.0,    1.0,    1.0,
2721     };
2722
2723     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2724     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2725
2726     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2727                                         &texture, NULL);
2728     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2729     if(!texture)
2730     {
2731         skip("Failed to create test texture\n");
2732         return;
2733     }
2734
2735     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2736     fill_surface(surface, 0xffff0000);
2737     IDirect3DSurface9_Release(surface);
2738     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2739     fill_surface(surface, 0xff00ff00);
2740     IDirect3DSurface9_Release(surface);
2741     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2742     fill_surface(surface, 0xff0000ff);
2743     IDirect3DSurface9_Release(surface);
2744
2745     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2746     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2747     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2748     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2749
2750     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2751     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2752
2753     hr = IDirect3DDevice9_BeginScene(device);
2754     if(SUCCEEDED(hr))
2755     {
2756         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2757         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2758         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2759         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2760
2761         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2762         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2763         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2764         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2765
2766         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2767         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2769         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2770
2771         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2772         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2774         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2775         hr = IDirect3DDevice9_EndScene(device);
2776     }
2777
2778     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2779     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2780     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2781     color = getPixelColor(device, 160, 360);
2782     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2783     color = getPixelColor(device, 160, 120);
2784     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2785     color = getPixelColor(device, 480, 120);
2786     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2787     color = getPixelColor(device, 480, 360);
2788     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2789
2790     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2791     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2792
2793     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2794     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2795
2796     hr = IDirect3DDevice9_BeginScene(device);
2797     if(SUCCEEDED(hr))
2798     {
2799         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2800         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2801         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2802         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2803
2804         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2805         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2806         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2807         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2808
2809         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2810         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2812         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2813
2814         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2815         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2816         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2817         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2818         hr = IDirect3DDevice9_EndScene(device);
2819     }
2820
2821     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2822     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2823     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2824     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2825
2826     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2827     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2828     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2829      * samples from the highest level in the texture(level 2)
2830      */
2831     color = getPixelColor(device, 160, 360);
2832     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2833     color = getPixelColor(device, 160, 120);
2834     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2835     color = getPixelColor(device, 480, 120);
2836     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2837     color = getPixelColor(device, 480, 360);
2838     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2839
2840     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2841     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2842     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2843     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2844     IDirect3DTexture9_Release(texture);
2845 }
2846
2847 static void release_buffer_test(IDirect3DDevice9 *device)
2848 {
2849     IDirect3DVertexBuffer9 *vb = NULL;
2850     IDirect3DIndexBuffer9 *ib = NULL;
2851     HRESULT hr;
2852     BYTE *data;
2853     LONG ref;
2854
2855     static const struct vertex quad[] = {
2856         {-1.0,      -1.0,       0.1,        0xffff0000},
2857         {-1.0,       1.0,       0.1,        0xffff0000},
2858         { 1.0,       1.0,       0.1,        0xffff0000},
2859
2860         {-1.0,      -1.0,       0.1,        0xff00ff00},
2861         {-1.0,       1.0,       0.1,        0xff00ff00},
2862         { 1.0,       1.0,       0.1,        0xff00ff00}
2863     };
2864     short indices[] = {3, 4, 5};
2865
2866     /* Index and vertex buffers should always be creatable */
2867     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2868                                               D3DPOOL_MANAGED, &vb, NULL);
2869     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2870     if(!vb) {
2871         skip("Failed to create a vertex buffer\n");
2872         return;
2873     }
2874     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2875     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2876     if(!ib) {
2877         skip("Failed to create an index buffer\n");
2878         return;
2879     }
2880
2881     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2882     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2883     memcpy(data, quad, sizeof(quad));
2884     hr = IDirect3DVertexBuffer9_Unlock(vb);
2885     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2886
2887     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2888     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2889     memcpy(data, indices, sizeof(indices));
2890     hr = IDirect3DIndexBuffer9_Unlock(ib);
2891     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2892
2893     hr = IDirect3DDevice9_SetIndices(device, ib);
2894     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2895     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2896     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2897     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2898     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2899
2900     /* Now destroy the bound index buffer and draw again */
2901     ref = IDirect3DIndexBuffer9_Release(ib);
2902     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
2903
2904     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2905     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2906
2907     hr = IDirect3DDevice9_BeginScene(device);
2908     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2909     if(SUCCEEDED(hr))
2910     {
2911         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2912          * making assumptions about the indices or vertices
2913          */
2914         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2915         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2916         hr = IDirect3DDevice9_EndScene(device);
2917         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2918     }
2919
2920     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2921     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2922
2923     hr = IDirect3DDevice9_SetIndices(device, NULL);
2924     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2925     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2926     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2927
2928     /* Index buffer was already destroyed as part of the test */
2929     IDirect3DVertexBuffer9_Release(vb);
2930 }
2931
2932 static void float_texture_test(IDirect3DDevice9 *device)
2933 {
2934     IDirect3D9 *d3d = NULL;
2935     HRESULT hr;
2936     IDirect3DTexture9 *texture = NULL;
2937     D3DLOCKED_RECT lr;
2938     float *data;
2939     DWORD color;
2940     float quad[] = {
2941         -1.0,      -1.0,       0.1,     0.0,    0.0,
2942         -1.0,       1.0,       0.1,     0.0,    1.0,
2943          1.0,      -1.0,       0.1,     1.0,    0.0,
2944          1.0,       1.0,       0.1,     1.0,    1.0,
2945     };
2946
2947     memset(&lr, 0, sizeof(lr));
2948     IDirect3DDevice9_GetDirect3D(device, &d3d);
2949     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2950                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2951         skip("D3DFMT_R32F textures not supported\n");
2952         goto out;
2953     }
2954
2955     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2956                                         D3DPOOL_MANAGED, &texture, NULL);
2957     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2958     if(!texture) {
2959         skip("Failed to create R32F texture\n");
2960         goto out;
2961     }
2962
2963     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2964     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2965     data = lr.pBits;
2966     *data = 0.0;
2967     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2968     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2969
2970     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2971     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2972
2973     hr = IDirect3DDevice9_BeginScene(device);
2974     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2975     if(SUCCEEDED(hr))
2976     {
2977         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2978         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2979
2980         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2981         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2982
2983         hr = IDirect3DDevice9_EndScene(device);
2984         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2985     }
2986     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2987     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2988
2989     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2990     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2991
2992     color = getPixelColor(device, 240, 320);
2993     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2994
2995 out:
2996     if(texture) IDirect3DTexture9_Release(texture);
2997     IDirect3D9_Release(d3d);
2998 }
2999
3000 static void g16r16_texture_test(IDirect3DDevice9 *device)
3001 {
3002     IDirect3D9 *d3d = NULL;
3003     HRESULT hr;
3004     IDirect3DTexture9 *texture = NULL;
3005     D3DLOCKED_RECT lr;
3006     DWORD *data;
3007     DWORD color, red, green, blue;
3008     float quad[] = {
3009        -1.0,      -1.0,       0.1,     0.0,    0.0,
3010        -1.0,       1.0,       0.1,     0.0,    1.0,
3011         1.0,      -1.0,       0.1,     1.0,    0.0,
3012         1.0,       1.0,       0.1,     1.0,    1.0,
3013     };
3014
3015     memset(&lr, 0, sizeof(lr));
3016     IDirect3DDevice9_GetDirect3D(device, &d3d);
3017     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3018        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3019            skip("D3DFMT_G16R16 textures not supported\n");
3020            goto out;
3021     }
3022
3023     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3024                                         D3DPOOL_MANAGED, &texture, NULL);
3025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3026     if(!texture) {
3027         skip("Failed to create D3DFMT_G16R16 texture\n");
3028         goto out;
3029     }
3030
3031     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3032     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3033     data = lr.pBits;
3034     *data = 0x0f00f000;
3035     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3036     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3037
3038     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3039     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3040
3041     hr = IDirect3DDevice9_BeginScene(device);
3042     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3043     if(SUCCEEDED(hr))
3044     {
3045         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3046         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3047
3048         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3049         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3050
3051         hr = IDirect3DDevice9_EndScene(device);
3052         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3053     }
3054     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3055     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3056
3057     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3058     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3059
3060     color = getPixelColor(device, 240, 320);
3061     red   = (color & 0x00ff0000) >> 16;
3062     green = (color & 0x0000ff00) >>  8;
3063     blue  = (color & 0x000000ff) >>  0;
3064     ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3065        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3066
3067 out:
3068     if(texture) IDirect3DTexture9_Release(texture);
3069     IDirect3D9_Release(d3d);
3070 }
3071
3072 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3073 {
3074     HRESULT hr;
3075     IDirect3D9 *d3d;
3076     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3077     D3DCAPS9 caps;
3078     IDirect3DTexture9 *texture = NULL;
3079     IDirect3DVolumeTexture9 *volume = NULL;
3080     unsigned int x, y, z;
3081     D3DLOCKED_RECT lr;
3082     D3DLOCKED_BOX lb;
3083     DWORD color;
3084     UINT w, h;
3085     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3086     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3087                            0.0, 1.0, 0.0, 0.0,
3088                            0.0, 0.0, 1.0, 0.0,
3089                            0.0, 0.0, 0.0, 1.0};
3090     static const D3DVERTEXELEMENT9 decl_elements[] = {
3091         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3092         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3093         D3DDECL_END()
3094     };
3095     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3096         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3097         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3098         D3DDECL_END()
3099     };
3100     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3101         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3102         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3103         D3DDECL_END()
3104     };
3105     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3106                                                  0x00, 0xff, 0x00, 0x00,
3107                                                  0x00, 0x00, 0x00, 0x00,
3108                                                  0x00, 0x00, 0x00, 0x00};
3109
3110     memset(&lr, 0, sizeof(lr));
3111     memset(&lb, 0, sizeof(lb));
3112     IDirect3DDevice9_GetDirect3D(device, &d3d);
3113     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3114                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3115         fmt = D3DFMT_A16B16G16R16;
3116     }
3117     IDirect3D9_Release(d3d);
3118
3119     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3120     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3121     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3122     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3123     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3124     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3125     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3126     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3127     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3128     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3129     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3130     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3131     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3133     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3134     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3135     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3136     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3137     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3138     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3139     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3140     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3141     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3142     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3143
3144     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3145     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3146     w = min(1024, caps.MaxTextureWidth);
3147     h = min(1024, caps.MaxTextureHeight);
3148     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3149                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3150     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3151     if(!texture) {
3152         skip("Failed to create the test texture\n");
3153         return;
3154     }
3155
3156     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3157      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3158      * 1.0 in red and green for the x and y coords
3159      */
3160     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3161     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3162     for(y = 0; y < h; y++) {
3163         for(x = 0; x < w; x++) {
3164             double r_f = (double) y / (double) h;
3165             double g_f = (double) x / (double) w;
3166             if(fmt == D3DFMT_A16B16G16R16) {
3167                 unsigned short r, g;
3168                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3169                 r = (unsigned short) (r_f * 65536.0);
3170                 g = (unsigned short) (g_f * 65536.0);
3171                 dst[0] = r;
3172                 dst[1] = g;
3173                 dst[2] = 0;
3174                 dst[3] = 65535;
3175             } else {
3176                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3177                 unsigned char r = (unsigned char) (r_f * 255.0);
3178                 unsigned char g = (unsigned char) (g_f * 255.0);
3179                 dst[0] = 0;
3180                 dst[1] = g;
3181                 dst[2] = r;
3182                 dst[3] = 255;
3183             }
3184         }
3185     }
3186     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3187     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3188     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3190
3191     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3192     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3193     hr = IDirect3DDevice9_BeginScene(device);
3194     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3195     if(SUCCEEDED(hr))
3196     {
3197         float quad1[] = {
3198             -1.0,      -1.0,       0.1,     1.0,    1.0,
3199             -1.0,       0.0,       0.1,     1.0,    1.0,
3200              0.0,      -1.0,       0.1,     1.0,    1.0,
3201              0.0,       0.0,       0.1,     1.0,    1.0,
3202         };
3203         float quad2[] = {
3204             -1.0,       0.0,       0.1,     1.0,    1.0,
3205             -1.0,       1.0,       0.1,     1.0,    1.0,
3206              0.0,       0.0,       0.1,     1.0,    1.0,
3207              0.0,       1.0,       0.1,     1.0,    1.0,
3208         };
3209         float quad3[] = {
3210              0.0,       0.0,       0.1,     0.5,    0.5,
3211              0.0,       1.0,       0.1,     0.5,    0.5,
3212              1.0,       0.0,       0.1,     0.5,    0.5,
3213              1.0,       1.0,       0.1,     0.5,    0.5,
3214         };
3215         float quad4[] = {
3216              320,       480,       0.1,     1.0,    0.0,    1.0,
3217              320,       240,       0.1,     1.0,    0.0,    1.0,
3218              640,       480,       0.1,     1.0,    0.0,    1.0,
3219              640,       240,       0.1,     1.0,    0.0,    1.0,
3220         };
3221         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3222                           0.0, 0.0, 0.0, 0.0,
3223                           0.0, 0.0, 0.0, 0.0,
3224                           0.0, 0.0, 0.0, 0.0};
3225
3226         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3227         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3228         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3230         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3231
3232         /* What happens with transforms enabled? */
3233         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3234         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3235         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3236         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3237
3238         /* What happens if 4 coords are used, but only 2 given ?*/
3239         mat[8] = 1.0;
3240         mat[13] = 1.0;
3241         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3242         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3243         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3244         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3245         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3246         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3247
3248         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3249          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3250          * due to the coords in the vertices. (turns out red, indeed)
3251          */
3252         memset(mat, 0, sizeof(mat));
3253         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3254         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3255         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3256         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3257         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3258         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3259         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3260         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3261
3262         hr = IDirect3DDevice9_EndScene(device);
3263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3264     }
3265     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3266     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3267     color = getPixelColor(device, 160, 360);
3268     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3269     color = getPixelColor(device, 160, 120);
3270     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3271     color = getPixelColor(device, 480, 120);
3272     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3273     color = getPixelColor(device, 480, 360);
3274     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3275
3276     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3277     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3278
3279     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3280     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3281     hr = IDirect3DDevice9_BeginScene(device);
3282     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3283     if(SUCCEEDED(hr))
3284     {
3285         float quad1[] = {
3286             -1.0,      -1.0,       0.1,     0.8,    0.2,
3287             -1.0,       0.0,       0.1,     0.8,    0.2,
3288              0.0,      -1.0,       0.1,     0.8,    0.2,
3289              0.0,       0.0,       0.1,     0.8,    0.2,
3290         };
3291         float quad2[] = {
3292             -1.0,       0.0,       0.1,     0.5,    1.0,
3293             -1.0,       1.0,       0.1,     0.5,    1.0,
3294              0.0,       0.0,       0.1,     0.5,    1.0,
3295              0.0,       1.0,       0.1,     0.5,    1.0,
3296         };
3297         float quad3[] = {
3298              0.0,       0.0,       0.1,     0.5,    1.0,
3299              0.0,       1.0,       0.1,     0.5,    1.0,
3300              1.0,       0.0,       0.1,     0.5,    1.0,
3301              1.0,       1.0,       0.1,     0.5,    1.0,
3302         };
3303         float quad4[] = {
3304              0.0,      -1.0,       0.1,     0.8,    0.2,
3305              0.0,       0.0,       0.1,     0.8,    0.2,
3306              1.0,      -1.0,       0.1,     0.8,    0.2,
3307              1.0,       0.0,       0.1,     0.8,    0.2,
3308         };
3309         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3310                           0.0, 0.0, 0.0, 0.0,
3311                           0.0, 1.0, 0.0, 0.0,
3312                           0.0, 0.0, 0.0, 0.0};
3313
3314         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3315          */
3316         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3317         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3318         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3319         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3320
3321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3322         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3323
3324         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3325          * it behaves like COUNT2 because normal textures require 2 coords
3326          */
3327         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3328         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3329         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3330         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3331
3332         /* Just to be sure, the same as quad2 above */
3333         memset(mat, 0, sizeof(mat));
3334         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3335         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3336         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3337         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3338         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3339         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3340
3341         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3342          * used? And what happens to the first?
3343          */
3344         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3345         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3346         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3347         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3348
3349         hr = IDirect3DDevice9_EndScene(device);
3350         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3351     }
3352     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3353     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3354     color = getPixelColor(device, 160, 360);
3355     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3356     color = getPixelColor(device, 160, 120);
3357     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3358     color = getPixelColor(device, 480, 120);
3359     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3360        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3361     color = getPixelColor(device, 480, 360);
3362     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3363        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3364
3365     IDirect3DTexture9_Release(texture);
3366
3367     /* Test projected textures, without any fancy matrices */
3368     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3369     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3370     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3372     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3373     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3374     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3375     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3376
3377     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379     for(x = 0; x < 4; x++) {
3380         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3381     }
3382     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3383     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3384     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3386
3387     hr = IDirect3DDevice9_BeginScene(device);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389     if(SUCCEEDED(hr))
3390     {
3391         const float proj_quads[] = {
3392            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3393             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3394            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3395             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3396            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3397             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3398            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3399             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3400         };
3401
3402         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3403         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3405         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3406
3407         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3408         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3410         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3411
3412         hr = IDirect3DDevice9_EndScene(device);
3413         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3414     }
3415
3416     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3417     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3418     IDirect3DTexture9_Release(texture);
3419
3420     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3421     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3422     color = getPixelColor(device, 158, 118);
3423     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3424     color = getPixelColor(device, 162, 118);
3425     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3426     color = getPixelColor(device, 158, 122);
3427     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3428     color = getPixelColor(device, 162, 122);
3429     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3430
3431     color = getPixelColor(device, 158, 178);
3432     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3433     color = getPixelColor(device, 162, 178);
3434     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3435     color = getPixelColor(device, 158, 182);
3436     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3437     color = getPixelColor(device, 162, 182);
3438     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3439
3440     color = getPixelColor(device, 318, 118);
3441     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3442     color = getPixelColor(device, 322, 118);
3443     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3444     color = getPixelColor(device, 318, 122);
3445     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3446     color = getPixelColor(device, 322, 122);
3447     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3448
3449     color = getPixelColor(device, 318, 178);
3450     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3451     color = getPixelColor(device, 322, 178);
3452     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3453     color = getPixelColor(device, 318, 182);
3454     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3455     color = getPixelColor(device, 322, 182);
3456     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3457
3458     color = getPixelColor(device, 238, 298);
3459     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3460     color = getPixelColor(device, 242, 298);
3461     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3462     color = getPixelColor(device, 238, 302);
3463     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3464     color = getPixelColor(device, 242, 302);
3465     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3466
3467     color = getPixelColor(device, 238, 388);
3468     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3469     color = getPixelColor(device, 242, 388);
3470     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3471     color = getPixelColor(device, 238, 392);
3472     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3473     color = getPixelColor(device, 242, 392);
3474     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3475
3476     color = getPixelColor(device, 478, 298);
3477     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3478     color = getPixelColor(device, 482, 298);
3479     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3480     color = getPixelColor(device, 478, 302);
3481     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3482     color = getPixelColor(device, 482, 302);
3483     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3484
3485     color = getPixelColor(device, 478, 388);
3486     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3487     color = getPixelColor(device, 482, 388);
3488     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3489     color = getPixelColor(device, 478, 392);
3490     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3491     color = getPixelColor(device, 482, 392);
3492     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3493
3494     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3495     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3496     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3497      * Thus watch out if sampling from texels between 0 and 1.
3498      */
3499     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3500     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3501        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3502     if(!volume) {
3503         skip("Failed to create a volume texture\n");
3504         goto out;
3505     }
3506
3507     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3508     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3509     for(z = 0; z < 32; z++) {
3510         for(y = 0; y < 32; y++) {
3511             for(x = 0; x < 32; x++) {
3512                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3513                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3514                 float r_f = (float) x / 31.0;
3515                 float g_f = (float) y / 31.0;
3516                 float b_f = (float) z / 31.0;
3517
3518                 if(fmt == D3DFMT_A16B16G16R16) {
3519                     unsigned short *mem_s = mem;
3520                     mem_s[0]  = r_f * 65535.0;
3521                     mem_s[1]  = g_f * 65535.0;
3522                     mem_s[2]  = b_f * 65535.0;
3523                     mem_s[3]  = 65535;
3524                 } else {
3525                     unsigned char *mem_c = mem;
3526                     mem_c[0]  = b_f * 255.0;
3527                     mem_c[1]  = g_f * 255.0;
3528                     mem_c[2]  = r_f * 255.0;
3529                     mem_c[3]  = 255;
3530                 }
3531             }
3532         }
3533     }
3534     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3535     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3536
3537     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3538     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3539
3540     hr = IDirect3DDevice9_BeginScene(device);
3541     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3542     if(SUCCEEDED(hr))
3543     {
3544         float quad1[] = {
3545             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3546             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3547              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3548              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3549         };
3550         float quad2[] = {
3551             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3552             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3553              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3554              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3555         };
3556         float quad3[] = {
3557              0.0,       0.0,       0.1,     0.0,    0.0,
3558              0.0,       1.0,       0.1,     0.0,    0.0,
3559              1.0,       0.0,       0.1,     0.0,    0.0,
3560              1.0,       1.0,       0.1,     0.0,    0.0
3561         };
3562         float quad4[] = {
3563              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3564              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3565              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3566              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3567         };
3568         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3569                          0.0, 0.0, 1.0, 0.0,
3570                          0.0, 1.0, 0.0, 0.0,
3571                          0.0, 0.0, 0.0, 1.0};
3572         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3573         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3574
3575         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3576          * values
3577          */
3578         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3579         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3580         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3581         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3582         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3583         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3584
3585         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3586          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3587          * otherwise the w will be missing(blue).
3588          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3589          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3590          */
3591         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3592         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3593         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3594         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3595
3596         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3597         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3598         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3599         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3600         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3602         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3603         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3604         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3605
3606         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3607          * disable. ATI extends it up to the amount of values needed for the volume texture
3608          */
3609         memset(mat, 0, sizeof(mat));
3610         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3611         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3612         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3613         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3614         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3615         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3616         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3617         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3618
3619         hr = IDirect3DDevice9_EndScene(device);
3620         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3621     }
3622     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3624
3625     color = getPixelColor(device, 160, 360);
3626     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3627     color = getPixelColor(device, 160, 120);
3628     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3629        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3630     color = getPixelColor(device, 480, 120);
3631     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3632     color = getPixelColor(device, 480, 360);
3633     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3634
3635     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3636     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3637     hr = IDirect3DDevice9_BeginScene(device);
3638     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3639     if(SUCCEEDED(hr))
3640     {
3641         float quad1[] = {
3642             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3643             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3644              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3645              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3646         };
3647         float quad2[] = {
3648             -1.0,       0.0,       0.1,
3649             -1.0,       1.0,       0.1,
3650              0.0,       0.0,       0.1,
3651              0.0,       1.0,       0.1,
3652         };
3653         float quad3[] = {
3654              0.0,       0.0,       0.1,     1.0,
3655              0.0,       1.0,       0.1,     1.0,
3656              1.0,       0.0,       0.1,     1.0,
3657              1.0,       1.0,       0.1,     1.0
3658         };
3659         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3660                            0.0, 0.0, 0.0, 0.0,
3661                            0.0, 0.0, 0.0, 0.0,
3662                            0.0, 1.0, 0.0, 0.0};
3663         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3664                            1.0, 0.0, 0.0, 0.0,
3665                            0.0, 1.0, 0.0, 0.0,
3666                            0.0, 0.0, 1.0, 0.0};
3667         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3668         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3669
3670         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3671          */
3672         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3673         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3674         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3675         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3676         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3677         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3678
3679         /* None passed */
3680         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3681         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3682         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3683         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3685         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3686
3687         /* 4 used, 1 passed */
3688         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3689         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3690         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3691         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3692         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3693         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3694
3695         hr = IDirect3DDevice9_EndScene(device);
3696         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3697     }
3698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3699     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3700     color = getPixelColor(device, 160, 360);
3701     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3702     color = getPixelColor(device, 160, 120);
3703     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3704     color = getPixelColor(device, 480, 120);
3705     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3706     /* Quad4: unused */
3707
3708     IDirect3DVolumeTexture9_Release(volume);
3709
3710     out:
3711     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3713     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3714     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3719     IDirect3DVertexDeclaration9_Release(decl);
3720     IDirect3DVertexDeclaration9_Release(decl2);
3721     IDirect3DVertexDeclaration9_Release(decl3);
3722 }
3723
3724 static void texdepth_test(IDirect3DDevice9 *device)
3725 {
3726     IDirect3DPixelShader9 *shader;
3727     HRESULT hr;
3728     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3729     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3730     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3731     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3732     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3733     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3734     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3735     DWORD shader_code[] = {
3736         0xffff0104,                                                                 /* ps_1_4               */
3737         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3738         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3739         0x0000fffd,                                                                 /* phase                */
3740         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3741         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3742         0x0000ffff                                                                  /* end                  */
3743     };
3744     DWORD color;
3745     float vertex[] = {
3746        -1.0,   -1.0,    0.0,
3747         1.0,   -1.0,    1.0,
3748        -1.0,    1.0,    0.0,
3749         1.0,    1.0,    1.0
3750     };
3751
3752     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3753     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3754
3755     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3756     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3757     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3758     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3759     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3761     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3762     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3764
3765     /* Fill the depth buffer with a gradient */
3766     hr = IDirect3DDevice9_BeginScene(device);
3767     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3768     if(SUCCEEDED(hr))
3769     {
3770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3771         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3772         hr = IDirect3DDevice9_EndScene(device);
3773         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3774     }
3775
3776     /* Now perform the actual tests. Same geometry, but with the shader */
3777     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3778     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3780     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3781     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3782     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3783
3784     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3785     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3786     hr = IDirect3DDevice9_BeginScene(device);
3787     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3788     if(SUCCEEDED(hr))
3789     {
3790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3791         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3792
3793         hr = IDirect3DDevice9_EndScene(device);
3794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3795     }
3796
3797     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3798     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3799     color = getPixelColor(device, 158, 240);
3800     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3801     color = getPixelColor(device, 162, 240);
3802     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3803
3804     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3805
3806     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3807     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3808     hr = IDirect3DDevice9_BeginScene(device);
3809     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3810     if(SUCCEEDED(hr))
3811     {
3812         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3813         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3814
3815         hr = IDirect3DDevice9_EndScene(device);
3816         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3817     }
3818
3819     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3820     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3821     color = getPixelColor(device, 318, 240);
3822     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3823     color = getPixelColor(device, 322, 240);
3824     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3825
3826     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3827
3828     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3829     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3830     hr = IDirect3DDevice9_BeginScene(device);
3831     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3832     if(SUCCEEDED(hr))
3833     {
3834         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3835         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3836
3837         hr = IDirect3DDevice9_EndScene(device);
3838         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3839     }
3840     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3841     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3842
3843     color = getPixelColor(device, 1, 240);
3844     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3845
3846     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3847
3848     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3849     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3850     hr = IDirect3DDevice9_BeginScene(device);
3851     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3852     if(SUCCEEDED(hr))
3853     {
3854         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3855         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3856
3857         hr = IDirect3DDevice9_EndScene(device);
3858         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3859     }
3860     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3861     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3862     color = getPixelColor(device, 318, 240);
3863     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3864     color = getPixelColor(device, 322, 240);
3865     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3866
3867     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3868
3869     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3870     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3871     hr = IDirect3DDevice9_BeginScene(device);
3872     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3873     if(SUCCEEDED(hr))
3874     {
3875         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3876         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3877
3878         hr = IDirect3DDevice9_EndScene(device);
3879         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3880     }
3881     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3882     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3883
3884     color = getPixelColor(device, 1, 240);
3885     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3886
3887     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3888
3889     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3890     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3891     hr = IDirect3DDevice9_BeginScene(device);
3892     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3893     if(SUCCEEDED(hr))
3894     {
3895         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3896         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3897
3898         hr = IDirect3DDevice9_EndScene(device);
3899         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3900     }
3901     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3902     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3903
3904     color = getPixelColor(device, 638, 240);
3905     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3906
3907     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3908
3909     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3910     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3911     hr = IDirect3DDevice9_BeginScene(device);
3912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3913     if(SUCCEEDED(hr))
3914     {
3915         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3916         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3917
3918         hr = IDirect3DDevice9_EndScene(device);
3919         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3920     }
3921     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3922     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3923
3924     color = getPixelColor(device, 638, 240);
3925     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3926
3927     /* Cleanup */
3928     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3929     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3930     IDirect3DPixelShader9_Release(shader);
3931
3932     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3933     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3935     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3936 }
3937
3938 static void texkill_test(IDirect3DDevice9 *device)
3939 {
3940     IDirect3DPixelShader9 *shader;
3941     HRESULT hr;
3942     DWORD color;
3943
3944     const float vertex[] = {
3945     /*                          bottom  top    right    left */
3946         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3947          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3948         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3949          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3950     };
3951
3952     DWORD shader_code_11[] = {
3953     0xffff0101,                                                             /* ps_1_1                     */
3954     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3955     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3956     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3957     0x0000ffff                                                              /* end                        */
3958     };
3959     DWORD shader_code_20[] = {
3960     0xffff0200,                                                             /* ps_2_0                     */
3961     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3962     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3963     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3964     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3965     0x0000ffff                                                              /* end                        */
3966     };
3967
3968     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3969     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3970     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3971     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3972
3973     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3974     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3975     hr = IDirect3DDevice9_BeginScene(device);
3976     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3977     if(SUCCEEDED(hr))
3978     {
3979         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3980         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3981         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3982         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3983         hr = IDirect3DDevice9_EndScene(device);
3984         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3985     }
3986     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3987     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3988     color = getPixelColor(device, 63, 46);
3989     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3990     color = getPixelColor(device, 66, 46);
3991     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3992     color = getPixelColor(device, 63, 49);
3993     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3994     color = getPixelColor(device, 66, 49);
3995     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3996
3997     color = getPixelColor(device, 578, 46);
3998     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3999     color = getPixelColor(device, 575, 46);
4000     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4001     color = getPixelColor(device, 578, 49);
4002     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4003     color = getPixelColor(device, 575, 49);
4004     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4005
4006     color = getPixelColor(device, 63, 430);
4007     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4008     color = getPixelColor(device, 63, 433);
4009     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4010     color = getPixelColor(device, 66, 433);
4011     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4012     color = getPixelColor(device, 66, 430);
4013     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4014
4015     color = getPixelColor(device, 578, 430);
4016     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4017     color = getPixelColor(device, 578, 433);
4018     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4019     color = getPixelColor(device, 575, 433);
4020     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4021     color = getPixelColor(device, 575, 430);
4022     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4023
4024     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4025     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4026     IDirect3DPixelShader9_Release(shader);
4027
4028     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4029     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4030     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4031     if(FAILED(hr)) {
4032         skip("Failed to create 2.0 test shader, most likely not supported\n");
4033         return;
4034     }
4035
4036     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4037     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4038     hr = IDirect3DDevice9_BeginScene(device);
4039     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4040     if(SUCCEEDED(hr))
4041     {
4042         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4043         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4044         hr = IDirect3DDevice9_EndScene(device);
4045         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4046     }
4047     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4048
4049     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4050     color = getPixelColor(device, 63, 46);
4051     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4052     color = getPixelColor(device, 66, 46);
4053     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4054     color = getPixelColor(device, 63, 49);
4055     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4056     color = getPixelColor(device, 66, 49);
4057     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4058
4059     color = getPixelColor(device, 578, 46);
4060     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4061     color = getPixelColor(device, 575, 46);
4062     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4063     color = getPixelColor(device, 578, 49);
4064     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4065     color = getPixelColor(device, 575, 49);
4066     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4067
4068     color = getPixelColor(device, 63, 430);
4069     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4070     color = getPixelColor(device, 63, 433);
4071     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4072     color = getPixelColor(device, 66, 433);
4073     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4074     color = getPixelColor(device, 66, 430);
4075     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4076
4077     color = getPixelColor(device, 578, 430);
4078     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4079     color = getPixelColor(device, 578, 433);
4080     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4081     color = getPixelColor(device, 575, 433);
4082     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4083     color = getPixelColor(device, 575, 430);
4084     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4085
4086     /* Cleanup */
4087     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4088     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4089     IDirect3DPixelShader9_Release(shader);
4090 }
4091
4092 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4093 {
4094     IDirect3D9 *d3d9;
4095     HRESULT hr;
4096     IDirect3DTexture9 *texture;
4097     IDirect3DPixelShader9 *shader;
4098     IDirect3DPixelShader9 *shader2;
4099     D3DLOCKED_RECT lr;
4100     DWORD color;
4101     DWORD shader_code[] = {
4102         0xffff0101,                             /* ps_1_1       */
4103         0x00000042, 0xb00f0000,                 /* tex t0       */
4104         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4105         0x0000ffff                              /* end          */
4106     };
4107     DWORD shader_code2[] = {
4108         0xffff0101,                             /* ps_1_1       */
4109         0x00000042, 0xb00f0000,                 /* tex t0       */
4110         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4111         0x0000ffff                              /* end          */
4112     };
4113
4114     float quad[] = {
4115        -1.0,   -1.0,   0.1,     0.5,    0.5,
4116         1.0,   -1.0,   0.1,     0.5,    0.5,
4117        -1.0,    1.0,   0.1,     0.5,    0.5,
4118         1.0,    1.0,   0.1,     0.5,    0.5,
4119     };
4120
4121     memset(&lr, 0, sizeof(lr));
4122     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4123     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4124                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4125     IDirect3D9_Release(d3d9);
4126     if(FAILED(hr)) {
4127         skip("No D3DFMT_X8L8V8U8 support\n");
4128     };
4129
4130     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4132
4133     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4134     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4135     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4136     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4137     *((DWORD *) lr.pBits) = 0x11ca3141;
4138     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4139     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4140
4141     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4142     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4143     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4145
4146     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4147     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4148     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4149     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4150     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4151     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4152
4153     hr = IDirect3DDevice9_BeginScene(device);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4155     if(SUCCEEDED(hr))
4156     {
4157         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4158         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4159
4160         hr = IDirect3DDevice9_EndScene(device);
4161         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4162     }
4163     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4164     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4165     color = getPixelColor(device, 578, 430);
4166     ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4167        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4168
4169     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4170     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4171     hr = IDirect3DDevice9_BeginScene(device);
4172     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4173     if(SUCCEEDED(hr))
4174     {
4175         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4176         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4177
4178         hr = IDirect3DDevice9_EndScene(device);
4179         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4180     }
4181     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4182     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4183     color = getPixelColor(device, 578, 430);
4184     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4185
4186     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4187     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4188     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4189     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4190     IDirect3DPixelShader9_Release(shader);
4191     IDirect3DPixelShader9_Release(shader2);
4192     IDirect3DTexture9_Release(texture);
4193 }
4194
4195 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4196 {
4197     HRESULT hr;
4198     IDirect3D9 *d3d;
4199     IDirect3DTexture9 *texture = NULL;
4200     IDirect3DSurface9 *surface;
4201     DWORD color;
4202     const RECT r1 = {256, 256, 512, 512};
4203     const RECT r2 = {512, 256, 768, 512};
4204     const RECT r3 = {256, 512, 512, 768};
4205     const RECT r4 = {512, 512, 768, 768};
4206     unsigned int x, y;
4207     D3DLOCKED_RECT lr;
4208     memset(&lr, 0, sizeof(lr));
4209
4210     IDirect3DDevice9_GetDirect3D(device, &d3d);
4211     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4212        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4213         skip("No autogenmipmap support\n");
4214         IDirect3D9_Release(d3d);
4215         return;
4216     }
4217     IDirect3D9_Release(d3d);
4218
4219     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4220     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4221
4222     /* Make the mipmap big, so that a smaller mipmap is used
4223      */
4224     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4225                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4226     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4227
4228     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4229     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4230     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4231     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4232     for(y = 0; y < 1024; y++) {
4233         for(x = 0; x < 1024; x++) {
4234             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4235             POINT pt;
4236
4237             pt.x = x;
4238             pt.y = y;
4239             if(PtInRect(&r1, pt)) {
4240                 *dst = 0xffff0000;
4241             } else if(PtInRect(&r2, pt)) {
4242                 *dst = 0xff00ff00;
4243             } else if(PtInRect(&r3, pt)) {
4244                 *dst = 0xff0000ff;
4245             } else if(PtInRect(&r4, pt)) {
4246                 *dst = 0xff000000;
4247             } else {
4248                 *dst = 0xffffffff;
4249             }
4250         }
4251     }
4252     hr = IDirect3DSurface9_UnlockRect(surface);
4253     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4254     IDirect3DSurface9_Release(surface);
4255
4256     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4257     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4258     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4260
4261     hr = IDirect3DDevice9_BeginScene(device);
4262     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4263     if(SUCCEEDED(hr)) {
4264         const float quad[] =  {
4265            -0.5,   -0.5,    0.1,    0.0,    0.0,
4266            -0.5,    0.5,    0.1,    0.0,    1.0,
4267             0.5,   -0.5,    0.1,    1.0,    0.0,
4268             0.5,    0.5,    0.1,    1.0,    1.0
4269         };
4270
4271         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4272         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4273         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4274         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4275         hr = IDirect3DDevice9_EndScene(device);
4276         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4277     }
4278     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4279     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4280     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4281     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4282     IDirect3DTexture9_Release(texture);
4283
4284     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4285     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4286     color = getPixelColor(device, 200, 200);
4287     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4288     color = getPixelColor(device, 280, 200);
4289     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4290     color = getPixelColor(device, 360, 200);
4291     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4292     color = getPixelColor(device, 440, 200);
4293     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4294     color = getPixelColor(device, 200, 270);
4295     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4296     color = getPixelColor(device, 280, 270);
4297     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4298     color = getPixelColor(device, 360, 270);
4299     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4300     color = getPixelColor(device, 440, 270);
4301     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4302 }
4303
4304 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4305 {
4306     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4307     IDirect3DVertexDeclaration9 *decl;
4308     HRESULT hr;
4309     DWORD color;
4310     DWORD shader_code_11[] =  {
4311         0xfffe0101,                                         /* vs_1_1           */
4312         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4313         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4314         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4315         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4316         0x0000ffff                                          /* end              */
4317     };
4318     DWORD shader_code_11_2[] =  {
4319         0xfffe0101,                                         /* vs_1_1           */
4320         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4321         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4322         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4323         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4324         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4325         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4326         0x0000ffff                                          /* end              */
4327     };
4328     DWORD shader_code_20[] =  {
4329         0xfffe0200,                                         /* vs_2_0           */
4330         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4331         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4332         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4333         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4334         0x0000ffff                                          /* end              */
4335     };
4336     DWORD shader_code_20_2[] =  {
4337         0xfffe0200,                                         /* vs_2_0           */
4338         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4339         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4340         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4341         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4342         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4343         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4344         0x0000ffff                                          /* end              */
4345     };
4346     static const D3DVERTEXELEMENT9 decl_elements[] = {
4347         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4348         D3DDECL_END()
4349     };
4350     float quad1[] = {
4351         -1.0,   -1.0,   0.1,
4352          0.0,   -1.0,   0.1,
4353         -1.0,    0.0,   0.1,
4354          0.0,    0.0,   0.1
4355     };
4356     float quad2[] = {
4357          0.0,   -1.0,   0.1,
4358          1.0,   -1.0,   0.1,
4359          0.0,    0.0,   0.1,
4360          1.0,    0.0,   0.1
4361     };
4362     float quad3[] = {
4363          0.0,    0.0,   0.1,
4364          1.0,    0.0,   0.1,
4365          0.0,    1.0,   0.1,
4366          1.0,    1.0,   0.1
4367     };
4368     float quad4[] = {
4369         -1.0,    0.0,   0.1,
4370          0.0,    0.0,   0.1,
4371         -1.0,    1.0,   0.1,
4372          0.0,    1.0,   0.1
4373     };
4374     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4375     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4376
4377     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4378     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4379
4380     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4381     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4382     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4383     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4384     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4385     if(FAILED(hr)) shader_20 = NULL;
4386     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4387     if(FAILED(hr)) shader_20_2 = NULL;
4388     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4389     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4390
4391     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4392     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4393     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4395     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4396     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4397
4398     hr = IDirect3DDevice9_BeginScene(device);
4399     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4400     if(SUCCEEDED(hr))
4401     {
4402         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4403         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4404         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4405         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4406
4407         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4408         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4410         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4411
4412         if(shader_20) {
4413             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4414             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4415             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4416             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4417         }
4418
4419         if(shader_20_2) {
4420             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4421             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4422             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4423             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4424         }
4425
4426         hr = IDirect3DDevice9_EndScene(device);
4427         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4428     }
4429     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4430     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4431
4432     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4433     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4434     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4435     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4436
4437     color = getPixelColor(device, 160, 360);
4438     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4439        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4440     color = getPixelColor(device, 480, 360);
4441     ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4442        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4443     if(shader_20) {
4444         color = getPixelColor(device, 160, 120);
4445         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4446            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4447     }
4448     if(shader_20_2) {
4449         color = getPixelColor(device, 480, 120);
4450         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4451            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4452     }
4453
4454     IDirect3DVertexDeclaration9_Release(decl);
4455     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4456     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4457     IDirect3DVertexShader9_Release(shader_11_2);
4458     IDirect3DVertexShader9_Release(shader_11);
4459 }
4460
4461 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4462 {
4463     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4464     HRESULT hr;
4465     DWORD color;
4466     DWORD shader_code_11[] =  {
4467         0xffff0101,                                         /* ps_1_1           */
4468         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4469         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4470         0x0000ffff                                          /* end              */
4471     };
4472     DWORD shader_code_12[] =  {
4473         0xffff0102,                                         /* ps_1_2           */
4474         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4475         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4476         0x0000ffff                                          /* end              */
4477     };
4478     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4479      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4480      * During development of this test, 1.3 shaders were verified too
4481      */
4482     DWORD shader_code_14[] =  {
4483         0xffff0104,                                         /* ps_1_4           */
4484         /* Try to make one constant local. It gets clamped too, although the binary contains
4485          * the bigger numbers
4486          */
4487         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4488         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4489         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4490         0x0000ffff                                          /* end              */
4491     };
4492     DWORD shader_code_20[] =  {
4493         0xffff0200,                                         /* ps_2_0           */
4494         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4495         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4496         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4497         0x0000ffff                                          /* end              */
4498     };
4499     float quad1[] = {
4500         -1.0,   -1.0,   0.1,
4501          0.0,   -1.0,   0.1,
4502         -1.0,    0.0,   0.1,
4503          0.0,    0.0,   0.1
4504     };
4505     float quad2[] = {
4506          0.0,   -1.0,   0.1,
4507          1.0,   -1.0,   0.1,
4508          0.0,    0.0,   0.1,
4509          1.0,    0.0,   0.1
4510     };
4511     float quad3[] = {
4512          0.0,    0.0,   0.1,
4513          1.0,    0.0,   0.1,
4514          0.0,    1.0,   0.1,
4515          1.0,    1.0,   0.1
4516     };
4517     float quad4[] = {
4518         -1.0,    0.0,   0.1,
4519          0.0,    0.0,   0.1,
4520         -1.0,    1.0,   0.1,
4521          0.0,    1.0,   0.1
4522     };
4523     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4524     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4525
4526     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4527     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4528
4529     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4530     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4531     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4532     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4533     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4535     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4536     if(FAILED(hr)) shader_20 = NULL;
4537
4538     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4540     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4541     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4542     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4543     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4544
4545     hr = IDirect3DDevice9_BeginScene(device);
4546     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4547     if(SUCCEEDED(hr))
4548     {
4549         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4550         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4551         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4552         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4553
4554         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4555         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4556         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4557         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4558
4559         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4560         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4561         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4562         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4563
4564         if(shader_20) {
4565             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4566             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4567             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4568             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4569         }
4570
4571         hr = IDirect3DDevice9_EndScene(device);
4572         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4573     }
4574     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4576
4577     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4578     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4579
4580     color = getPixelColor(device, 160, 360);
4581     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4582        "quad 1 has color %08x, expected 0x00808000\n", color);
4583     color = getPixelColor(device, 480, 360);
4584     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4585        "quad 2 has color %08x, expected 0x00808000\n", color);
4586     color = getPixelColor(device, 480, 120);
4587     ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4588        "quad 3 has color %08x, expected 0x00808000\n", color);
4589     if(shader_20) {
4590         color = getPixelColor(device, 160, 120);
4591         ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4592            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4593     }
4594
4595     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4596     IDirect3DPixelShader9_Release(shader_14);
4597     IDirect3DPixelShader9_Release(shader_12);
4598     IDirect3DPixelShader9_Release(shader_11);
4599 }
4600
4601 static void dp2add_ps_test(IDirect3DDevice9 *device)
4602 {
4603     IDirect3DPixelShader9 *shader_dp2add = NULL;
4604     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4605     HRESULT hr;
4606     DWORD color;
4607
4608     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4609      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4610      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4611      * r0 first.
4612      * The result here for the r,g,b components should be roughly 0.5:
4613      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4614     static const DWORD shader_code_dp2add[] =  {
4615         0xffff0200,                                                             /* ps_2_0                       */
4616         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4617
4618         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4619         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4620
4621         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4622         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4623         0x0000ffff                                                              /* end                          */
4624     };
4625
4626     /* Test the _sat modifier, too.  Result here should be:
4627      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4628      *      _SAT: ==> 1.0
4629      *   ADD: (1.0 + -0.5) = 0.5
4630      */
4631     static const DWORD shader_code_dp2add_sat[] =  {
4632         0xffff0200,                                                             /* ps_2_0                           */
4633         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4634
4635         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4636         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4637         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4638
4639         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4640         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4641         0x0000ffff                                                              /* end                              */
4642     };
4643
4644     const float quad[] = {
4645         -1.0,   -1.0,   0.1,
4646          1.0,   -1.0,   0.1,
4647         -1.0,    1.0,   0.1,
4648          1.0,    1.0,   0.1
4649     };
4650
4651
4652     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4653     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4654
4655     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4656     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4657
4658     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4659     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4660
4661     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4662     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4663
4664     if (shader_dp2add) {
4665
4666         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4667         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4668
4669         hr = IDirect3DDevice9_BeginScene(device);
4670         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4671         if(SUCCEEDED(hr))
4672         {
4673             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4674             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4675
4676             hr = IDirect3DDevice9_EndScene(device);
4677             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4678         }
4679         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4680         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4681
4682         color = getPixelColor(device, 360, 240);
4683         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4684
4685         IDirect3DPixelShader9_Release(shader_dp2add);
4686     } else {
4687         skip("dp2add shader creation failed\n");
4688     }
4689
4690     if (shader_dp2add_sat) {
4691
4692         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4693         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4694
4695         hr = IDirect3DDevice9_BeginScene(device);
4696         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4697         if(SUCCEEDED(hr))
4698         {
4699             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4700             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4701
4702             hr = IDirect3DDevice9_EndScene(device);
4703             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4704         }
4705         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4706         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4707
4708         color = getPixelColor(device, 360, 240);
4709         ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4710
4711         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4712     } else {
4713         skip("dp2add shader creation failed\n");
4714     }
4715
4716     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4717     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4718 }
4719
4720 static void cnd_test(IDirect3DDevice9 *device)
4721 {
4722     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4723     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4724     HRESULT hr;
4725     DWORD color;
4726     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4727      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4728      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4729      */
4730     DWORD shader_code_11[] =  {
4731         0xffff0101,                                                                 /* ps_1_1               */
4732         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4733         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4734         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4735         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4736         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4737         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4738         0x0000ffff                                                                  /* end                  */
4739     };
4740     DWORD shader_code_12[] =  {
4741         0xffff0102,                                                                 /* ps_1_2               */
4742         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4743         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4744         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4745         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4746         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4747         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4748         0x0000ffff                                                                  /* end                  */
4749     };
4750     DWORD shader_code_13[] =  {
4751         0xffff0103,                                                                 /* ps_1_3               */
4752         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4753         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4754         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4755         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4756         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4757         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4758         0x0000ffff                                                                  /* end                  */
4759     };
4760     DWORD shader_code_14[] =  {
4761         0xffff0104,                                                                 /* ps_1_3               */
4762         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4763         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4764         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4765         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4766         0x0000ffff                                                                  /* end                  */
4767     };
4768
4769     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4770      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4771      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4772      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4773      * native CreatePixelShader returns an error.
4774      *
4775      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4776      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4777      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4778      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4779      */
4780     DWORD shader_code_11_coissue[] =  {
4781         0xffff0101,                                                             /* ps_1_1                   */
4782         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4783         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4784         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4785         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4786         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4787         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4788         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4789         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4790         /* 0x40000000 = D3DSI_COISSUE */
4791         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4792         0x0000ffff                                                              /* end                      */
4793     };
4794     DWORD shader_code_12_coissue[] =  {
4795         0xffff0102,                                                             /* ps_1_2                   */
4796         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4797         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4798         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4799         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4800         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4801         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4802         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4803         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4804         /* 0x40000000 = D3DSI_COISSUE */
4805         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4806         0x0000ffff                                                              /* end                      */
4807     };
4808     DWORD shader_code_13_coissue[] =  {
4809         0xffff0103,                                                             /* ps_1_3                   */
4810         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4811         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4812         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4813         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4814         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4815         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4816         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4817         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4818         /* 0x40000000 = D3DSI_COISSUE */
4819         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4820         0x0000ffff                                                              /* end                      */
4821     };
4822     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4823      * compare against 0.5
4824      */
4825     DWORD shader_code_14_coissue[] =  {
4826         0xffff0104,                                                             /* ps_1_4                   */
4827         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4828         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4829         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4830         /* 0x40000000 = D3DSI_COISSUE */
4831         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4832         0x0000ffff                                                              /* end                      */
4833     };
4834     float quad1[] = {
4835         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4836          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4837         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4838          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4839     };
4840     float quad2[] = {
4841          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4842          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4843          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4844          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4845     };
4846     float quad3[] = {
4847          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4848          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4849          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4850          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4851     };
4852     float quad4[] = {
4853         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4854          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4855         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4856          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4857     };
4858     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4859     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4860     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4861     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4862
4863     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4864     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4865
4866     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4867     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4868     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4869     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4870     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4871     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4872     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4873     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4874     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4875     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4876     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4877     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4878     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4879     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4880     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4881     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4882
4883     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4884     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4885     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4886     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4887     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4888     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4889
4890     hr = IDirect3DDevice9_BeginScene(device);
4891     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4892     if(SUCCEEDED(hr))
4893     {
4894         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4895         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4896         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4897         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4898
4899         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4900         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4902         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4903
4904         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4905         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4906         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4907         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4908
4909         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4910         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4911         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4912         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4913
4914         hr = IDirect3DDevice9_EndScene(device);
4915         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4916     }
4917     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4918     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4919
4920     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4921     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4922
4923     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4924     color = getPixelColor(device, 158, 118);
4925     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4926     color = getPixelColor(device, 162, 118);
4927     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4928     color = getPixelColor(device, 158, 122);
4929     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4930     color = getPixelColor(device, 162, 122);
4931     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4932
4933     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4934     color = getPixelColor(device, 158, 358);
4935     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4936     color = getPixelColor(device, 162, 358);
4937     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4938         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4939     color = getPixelColor(device, 158, 362);
4940     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4941     color = getPixelColor(device, 162, 362);
4942     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4943         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4944
4945     /* 1.2 shader */
4946     color = getPixelColor(device, 478, 358);
4947     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4948     color = getPixelColor(device, 482, 358);
4949     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4950         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4951     color = getPixelColor(device, 478, 362);
4952     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4953     color = getPixelColor(device, 482, 362);
4954     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4955         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4956
4957     /* 1.3 shader */
4958     color = getPixelColor(device, 478, 118);
4959     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4960     color = getPixelColor(device, 482, 118);
4961     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4962         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4963     color = getPixelColor(device, 478, 122);
4964     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4965     color = getPixelColor(device, 482, 122);
4966     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4967         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4968
4969     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4970     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4971     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4972     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4973     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4974     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4975
4976     hr = IDirect3DDevice9_BeginScene(device);
4977     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4978     if(SUCCEEDED(hr))
4979     {
4980         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4981         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4982         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4983         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4984
4985         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4986         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4987         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4988         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4989
4990         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4991         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4993         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4994
4995         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4996         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4997         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4998         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4999
5000         hr = IDirect3DDevice9_EndScene(device);
5001         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5002     }
5003     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5004     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5005
5006     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5007     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5008
5009     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5010      * that we swapped the values in c1 and c2 to make the other tests return some color
5011      */
5012     color = getPixelColor(device, 158, 118);
5013     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5014     color = getPixelColor(device, 162, 118);
5015     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5016     color = getPixelColor(device, 158, 122);
5017     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5018     color = getPixelColor(device, 162, 122);
5019     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5020
5021     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5022     color = getPixelColor(device, 158, 358);
5023     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5024         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5025     color = getPixelColor(device, 162, 358);
5026     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5027         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5028     color = getPixelColor(device, 158, 362);
5029     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5030         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5031     color = getPixelColor(device, 162, 362);
5032     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5033         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5034
5035     /* 1.2 shader */
5036     color = getPixelColor(device, 478, 358);
5037     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5038         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5039     color = getPixelColor(device, 482, 358);
5040     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5041         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5042     color = getPixelColor(device, 478, 362);
5043     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5044         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5045     color = getPixelColor(device, 482, 362);
5046     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5047         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5048
5049     /* 1.3 shader */
5050     color = getPixelColor(device, 478, 118);
5051     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5052         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5053     color = getPixelColor(device, 482, 118);
5054     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5055         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5056     color = getPixelColor(device, 478, 122);
5057     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5058         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5059     color = getPixelColor(device, 482, 122);
5060     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5061         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5062
5063     IDirect3DPixelShader9_Release(shader_14_coissue);
5064     IDirect3DPixelShader9_Release(shader_13_coissue);
5065     IDirect3DPixelShader9_Release(shader_12_coissue);
5066     IDirect3DPixelShader9_Release(shader_11_coissue);
5067     IDirect3DPixelShader9_Release(shader_14);
5068     IDirect3DPixelShader9_Release(shader_13);
5069     IDirect3DPixelShader9_Release(shader_12);
5070     IDirect3DPixelShader9_Release(shader_11);
5071 }
5072
5073 static void nested_loop_test(IDirect3DDevice9 *device) {
5074     const DWORD shader_code[] = {
5075         0xffff0300,                                                             /* ps_3_0               */
5076         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5077         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5078         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5079         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5080         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5081         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5082         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5083         0x0000001d,                                                             /* endloop              */
5084         0x0000001d,                                                             /* endloop              */
5085         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5086         0x0000ffff                                                              /* end                  */
5087     };
5088     IDirect3DPixelShader9 *shader;
5089     HRESULT hr;
5090     DWORD color;
5091     const float quad[] = {
5092         -1.0,   -1.0,   0.1,
5093          1.0,   -1.0,   0.1,
5094         -1.0,    1.0,   0.1,
5095          1.0,    1.0,   0.1
5096     };
5097
5098     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5099     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5100     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5101     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5102     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5103     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5104     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5105     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5106
5107     hr = IDirect3DDevice9_BeginScene(device);
5108     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5109     if(SUCCEEDED(hr))
5110     {
5111         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5112         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5113         hr = IDirect3DDevice9_EndScene(device);
5114         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5115     }
5116     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5117     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5118
5119     color = getPixelColor(device, 360, 240);
5120     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5121        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5122
5123     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5124     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5125     IDirect3DPixelShader9_Release(shader);
5126 }
5127
5128 struct varying_test_struct
5129 {
5130     const DWORD             *shader_code;
5131     IDirect3DPixelShader9   *shader;
5132     DWORD                   color, color_rhw;
5133     const char              *name;
5134     BOOL                    todo, todo_rhw;
5135 };
5136
5137 struct hugeVertex
5138 {
5139     float pos_x,        pos_y,      pos_z,      rhw;
5140     float weight_1,     weight_2,   weight_3,   weight_4;
5141     float index_1,      index_2,    index_3,    index_4;
5142     float normal_1,     normal_2,   normal_3,   normal_4;
5143     float fog_1,        fog_2,      fog_3,      fog_4;
5144     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5145     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5146     float binormal_1,   binormal_2, binormal_3, binormal_4;
5147     float depth_1,      depth_2,    depth_3,    depth_4;
5148     DWORD diffuse, specular;
5149 };
5150
5151 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5152     /* dcl_position: fails to compile */
5153     const DWORD blendweight_code[] = {
5154         0xffff0300,                             /* ps_3_0                   */
5155         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5156         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5157         0x0000ffff                              /* end                      */
5158     };
5159     const DWORD blendindices_code[] = {
5160         0xffff0300,                             /* ps_3_0                   */
5161         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5162         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5163         0x0000ffff                              /* end                      */
5164     };
5165     const DWORD normal_code[] = {
5166         0xffff0300,                             /* ps_3_0                   */
5167         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5168         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5169         0x0000ffff                              /* end                      */
5170     };
5171     /* psize: fails? */
5172     const DWORD texcoord0_code[] = {
5173         0xffff0300,                             /* ps_3_0                   */
5174         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5175         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5176         0x0000ffff                              /* end                      */
5177     };
5178     const DWORD tangent_code[] = {
5179         0xffff0300,                             /* ps_3_0                   */
5180         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5181         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5182         0x0000ffff                              /* end                      */
5183     };
5184     const DWORD binormal_code[] = {
5185         0xffff0300,                             /* ps_3_0                   */
5186         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5187         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5188         0x0000ffff                              /* end                      */
5189     };
5190     /* tessfactor: fails */
5191     /* positiont: fails */
5192     const DWORD color_code[] = {
5193         0xffff0300,                             /* ps_3_0                   */
5194         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5195         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5196         0x0000ffff                              /* end                      */
5197     };
5198     const DWORD fog_code[] = {
5199         0xffff0300,                             /* ps_3_0                   */
5200         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5201         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5202         0x0000ffff                              /* end                      */
5203     };
5204     const DWORD depth_code[] = {
5205         0xffff0300,                             /* ps_3_0                   */
5206         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5207         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5208         0x0000ffff                              /* end                      */
5209     };
5210     const DWORD specular_code[] = {
5211         0xffff0300,                             /* ps_3_0                   */
5212         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5213         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5214         0x0000ffff                              /* end                      */
5215     };
5216     /* sample: fails */
5217
5218     struct varying_test_struct tests[] = {
5219        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5220        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5221        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5222        /* Why does dx not forward the texcoord? */
5223        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5224        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5225        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5226        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5227        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5228        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5229        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5230     };
5231     /* Declare a monster vertex type :-) */
5232     static const D3DVERTEXELEMENT9 decl_elements[] = {
5233         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5234         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5235         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5236         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5237         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5238         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5239         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5240         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5241         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5242         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5243         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5244         D3DDECL_END()
5245     };
5246     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5247         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5248         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5249         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5250         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5251         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5252         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5253         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5254         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5255         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5256         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5257         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5258         D3DDECL_END()
5259     };
5260     struct hugeVertex data[4] = {
5261         {
5262             -1.0,   -1.0,   0.1,    1.0,
5263              0.1,    0.1,   0.1,    0.1,
5264              0.2,    0.2,   0.2,    0.2,
5265              0.3,    0.3,   0.3,    0.3,
5266              0.4,    0.4,   0.4,    0.4,
5267              0.50,   0.55,  0.55,   0.55,
5268              0.6,    0.6,   0.6,    0.7,
5269              0.7,    0.7,   0.7,    0.6,
5270              0.8,    0.8,   0.8,    0.8,
5271              0xe6e6e6e6, /* 0.9 * 256 */
5272              0x224488ff  /* Nothing special */
5273         },
5274         {
5275              1.0,   -1.0,   0.1,    1.0,
5276              0.1,    0.1,   0.1,    0.1,
5277              0.2,    0.2,   0.2,    0.2,
5278              0.3,    0.3,   0.3,    0.3,
5279              0.4,    0.4,   0.4,    0.4,
5280              0.50,   0.55,  0.55,   0.55,
5281              0.6,    0.6,   0.6,    0.7,
5282              0.7,    0.7,   0.7,    0.6,
5283              0.8,    0.8,   0.8,    0.8,
5284              0xe6e6e6e6, /* 0.9 * 256 */
5285              0x224488ff /* Nothing special */
5286         },
5287         {
5288             -1.0,    1.0,   0.1,    1.0,
5289              0.1,    0.1,   0.1,    0.1,
5290              0.2,    0.2,   0.2,    0.2,
5291              0.3,    0.3,   0.3,    0.3,
5292              0.4,    0.4,   0.4,    0.4,
5293              0.50,   0.55,  0.55,   0.55,
5294              0.6,    0.6,   0.6,    0.7,
5295              0.7,    0.7,   0.7,    0.6,
5296              0.8,    0.8,   0.8,    0.8,
5297              0xe6e6e6e6, /* 0.9 * 256 */
5298              0x224488ff /* Nothing special */
5299         },
5300         {
5301              1.0,    1.0,   0.1,    1.0,
5302              0.1,    0.1,   0.1,    0.1,
5303              0.2,    0.2,   0.2,    0.2,
5304              0.3,    0.3,   0.3,    0.3,
5305              0.4,    0.4,   0.4,    0.4,
5306              0.50,   0.55,  0.55,   0.55,
5307              0.6,    0.6,   0.6,    0.7,
5308              0.7,    0.7,   0.7,    0.6,
5309              0.8,    0.8,   0.8,    0.8,
5310              0xe6e6e6e6, /* 0.9 * 256 */
5311              0x224488ff /* Nothing special */
5312         },
5313     };
5314     struct hugeVertex data2[4];
5315     IDirect3DVertexDeclaration9 *decl;
5316     IDirect3DVertexDeclaration9 *decl2;
5317     HRESULT hr;
5318     unsigned int i;
5319     DWORD color, r, g, b, r_e, g_e, b_e;
5320     BOOL drawok;
5321
5322     memcpy(data2, data, sizeof(data2));
5323     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5324     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5325     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5326     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5327
5328     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5329     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5330     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5331     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5332     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5333     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5334
5335     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5336     {
5337         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5338         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5339            tests[i].name, hr);
5340     }
5341
5342     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5343     {
5344         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5345         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5346
5347         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5348         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5349
5350         hr = IDirect3DDevice9_BeginScene(device);
5351         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5352         drawok = FALSE;
5353         if(SUCCEEDED(hr))
5354         {
5355             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5356             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5357             drawok = SUCCEEDED(hr);
5358             hr = IDirect3DDevice9_EndScene(device);
5359             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5360         }
5361         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5362         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5363
5364         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5365          * the failure and do not check the color if it failed
5366          */
5367         if(!drawok) {
5368             continue;
5369         }
5370
5371         color = getPixelColor(device, 360, 240);
5372         r = color & 0x00ff0000 >> 16;
5373         g = color & 0x0000ff00 >>  8;
5374         b = color & 0x000000ff;
5375         r_e = tests[i].color & 0x00ff0000 >> 16;
5376         g_e = tests[i].color & 0x0000ff00 >>  8;
5377         b_e = tests[i].color & 0x000000ff;
5378
5379         if(tests[i].todo) {
5380             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5381                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5382                          tests[i].name, color, tests[i].color);
5383         } else {
5384             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5385                "Test %s returned color 0x%08x, expected 0x%08x\n",
5386                tests[i].name, color, tests[i].color);
5387         }
5388     }
5389
5390     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5391     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5392     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5393     {
5394         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5395         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5396
5397         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5398         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5399
5400         hr = IDirect3DDevice9_BeginScene(device);
5401         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5402         if(SUCCEEDED(hr))
5403         {
5404             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5405             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5406             hr = IDirect3DDevice9_EndScene(device);
5407             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5408         }
5409         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5410         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5411
5412         color = getPixelColor(device, 360, 240);
5413         r = color & 0x00ff0000 >> 16;
5414         g = color & 0x0000ff00 >>  8;
5415         b = color & 0x000000ff;
5416         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5417         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5418         b_e = tests[i].color_rhw & 0x000000ff;
5419
5420         if(tests[i].todo_rhw) {
5421             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5422              * pipeline
5423              */
5424             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5425                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5426                          tests[i].name, color, tests[i].color_rhw);
5427         } else {
5428             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5429                "Test %s returned color 0x%08x, expected 0x%08x\n",
5430                tests[i].name, color, tests[i].color_rhw);
5431         }
5432     }
5433
5434     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5435     {
5436         IDirect3DPixelShader9_Release(tests[i].shader);
5437     }
5438
5439     IDirect3DVertexDeclaration9_Release(decl2);
5440     IDirect3DVertexDeclaration9_Release(decl);
5441 }
5442
5443 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5444     static const DWORD ps_code[] = {
5445     0xffff0300,                                                             /* ps_3_0                       */
5446     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5447     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5448     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5449     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5450     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5451     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5452     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5453     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5454     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5455
5456     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5457     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5458     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5459     0x0000001d,                                                             /* endloop                      */
5460     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5461     0x0000ffff                                                              /* end                          */
5462     };
5463     static const DWORD vs_1_code[] = {
5464     0xfffe0101,                                                             /* vs_1_1                       */
5465     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5466     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5467     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5468     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5469     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5470     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5471     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5472     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5473     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5474     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5475     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5476     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5477     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5478     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5479     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5480     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5481     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5482     0x0000ffff
5483     };
5484     DWORD vs_2_code[] = {
5485     0xfffe0200,                                                             /* vs_2_0                       */
5486     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5487     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5488     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5489     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5490     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5491     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5492     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5493     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5494     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5495     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5496     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5497     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5498     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5499     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5500     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5501     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5502     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5503     0x0000ffff                                                              /* end                          */
5504     };
5505     /* TODO: Define normal, tangent, blendweight and depth here */
5506     static const DWORD vs_3_code[] = {
5507     0xfffe0300,                                                             /* vs_3_0                       */
5508     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5509     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5510     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5511     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5512     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5513     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5514     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5515     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5516     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5517     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5518     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5519     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5520     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5521     0x0000ffff                                                              /* end                          */
5522     };
5523     float quad1[] =  {
5524         -1.0,   -1.0,   0.1,
5525          0.0,   -1.0,   0.1,
5526         -1.0,    0.0,   0.1,
5527          0.0,    0.0,   0.1
5528     };
5529     float quad2[] =  {
5530          0.0,   -1.0,   0.1,
5531          1.0,   -1.0,   0.1,
5532          0.0,    0.0,   0.1,
5533          1.0,    0.0,   0.1
5534     };
5535     float quad3[] =  {
5536         -1.0,    0.0,   0.1,
5537          0.0,    0.0,   0.1,
5538         -1.0,    1.0,   0.1,
5539          0.0,    1.0,   0.1
5540     };
5541
5542     HRESULT hr;
5543     DWORD color;
5544     IDirect3DPixelShader9 *pixelshader = NULL;
5545     IDirect3DVertexShader9 *vs_1_shader = NULL;
5546     IDirect3DVertexShader9 *vs_2_shader = NULL;
5547     IDirect3DVertexShader9 *vs_3_shader = NULL;
5548
5549     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5550
5551     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5552     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5553     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5554     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5555     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5556     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5557     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5558     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5559     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5560     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5561     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5562
5563     hr = IDirect3DDevice9_BeginScene(device);
5564     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5565     if(SUCCEEDED(hr))
5566     {
5567         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5568         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5570         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5571
5572         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5573         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5574         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5575         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5576
5577         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5578         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5579         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5580         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5581
5582         hr = IDirect3DDevice9_EndScene(device);
5583         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5584     }
5585     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5586     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5587
5588     color = getPixelColor(device, 160, 120);
5589     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5590        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5591     /* Accept two ways of oFog handling:
5592      *
5593      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5594      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5595      *
5596      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5597      *    This happens with software vertex processing and on Intel cards
5598      *
5599      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5600      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5601      */
5602     color = getPixelColor(device, 160, 360);
5603     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5604        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5605        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5606     color = getPixelColor(device, 480, 360);
5607     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5608        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5609        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5610
5611     /* cleanup */
5612     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5613     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5614     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5615     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5616     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5617     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5618     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5619     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5620 }
5621
5622 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5623     static const DWORD vs_code[] = {
5624     0xfffe0300,                                                             /* vs_3_0                       */
5625     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5626     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5627     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5628     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5629     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5630     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5631     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5632     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5633     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5634     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5635     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5636     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5637     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5638
5639     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5640     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5641     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5642     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5643     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5644     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5645     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5646     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5647     0x0000ffff                                                              /* end                          */
5648     };
5649     static const DWORD ps_1_code[] = {
5650     0xffff0104,                                                             /* ps_1_4                       */
5651     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5652     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5653     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5654     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5655     0x0000ffff                                                              /* end                          */
5656     };
5657     static const DWORD ps_2_code[] = {
5658     0xffff0200,                                                             /* ps_2_0                       */
5659     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5660     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5661     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5662
5663     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5664     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5665     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5666     0x0000ffff                                                              /* end                          */
5667     };
5668     static const DWORD ps_3_code[] = {
5669     0xffff0300,                                                             /* ps_3_0                       */
5670     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5671     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5672     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5673
5674     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5675     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5676     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5677     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5678     0x0000ffff                                                              /* end                          */
5679     };
5680
5681     float quad1[] =  {
5682         -1.0,   -1.0,   0.1,
5683          0.0,   -1.0,   0.1,
5684         -1.0,    0.0,   0.1,
5685          0.0,    0.0,   0.1
5686     };
5687     float quad2[] =  {
5688          0.0,   -1.0,   0.1,
5689          1.0,   -1.0,   0.1,
5690          0.0,    0.0,   0.1,
5691          1.0,    0.0,   0.1
5692     };
5693     float quad3[] =  {
5694         -1.0,    0.0,   0.1,
5695          0.0,    0.0,   0.1,
5696         -1.0,    1.0,   0.1,
5697          0.0,    1.0,   0.1
5698     };
5699     float quad4[] =  {
5700          0.0,    0.0,   0.1,
5701          1.0,    0.0,   0.1,
5702          0.0,    1.0,   0.1,
5703          1.0,    1.0,   0.1
5704     };
5705
5706     HRESULT hr;
5707     DWORD color;
5708     IDirect3DVertexShader9 *vertexshader = NULL;
5709     IDirect3DPixelShader9 *ps_1_shader = NULL;
5710     IDirect3DPixelShader9 *ps_2_shader = NULL;
5711     IDirect3DPixelShader9 *ps_3_shader = NULL;
5712     IDirect3DTexture9 *texture = NULL;
5713     D3DLOCKED_RECT lr;
5714     unsigned int x, y;
5715
5716     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5717
5718     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5720     if(FAILED(hr)) {
5721         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5722         return;
5723     }
5724     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5725     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5726     for(y = 0; y < 512; y++) {
5727         for(x = 0; x < 512; x++) {
5728             double r_f = (double) x / (double) 512;
5729             double g_f = (double) y / (double) 512;
5730             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5731             unsigned short r = (unsigned short) (r_f * 65535.0);
5732             unsigned short g = (unsigned short) (g_f * 65535.0);
5733             dst[0] = r;
5734             dst[1] = g;
5735             dst[2] = 0;
5736             dst[3] = 65535;
5737         }
5738     }
5739     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5740     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5741
5742     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5743     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5744     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5745     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5746     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5747     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5748     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5749     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5750     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5751     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5752     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5753
5754     hr = IDirect3DDevice9_BeginScene(device);
5755     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5756     if(SUCCEEDED(hr))
5757     {
5758         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5759         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5760         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5761         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5762
5763         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5764         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5765         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5766         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5767
5768         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5769         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5771         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5772
5773         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5774         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5775         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5776         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5777         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5778         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5779         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5780         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5781         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5782         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5783
5784         hr = IDirect3DDevice9_EndScene(device);
5785         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5786     }
5787     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5788     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5789
5790     color = getPixelColor(device, 160, 120);
5791     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5792        (color & 0x0000ff00) == 0x0000ff00 &&
5793        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5794        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5795     color = getPixelColor(device, 160, 360);
5796     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5797        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5798        (color & 0x000000ff) == 0x00000000,
5799        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5800     color = getPixelColor(device, 480, 360);
5801     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5802        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5803        (color & 0x000000ff) == 0x00000000,
5804        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5805     color = getPixelColor(device, 480, 160);
5806     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5807        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5808        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5809        (color & 0x000000ff) == 0x00000000),
5810        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5811
5812     /* cleanup */
5813     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5814     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5815     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5816     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5817     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5818     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5819     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5820     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5821     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5822     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5823     if(texture) IDirect3DTexture9_Release(texture);
5824 }
5825
5826 static void test_compare_instructions(IDirect3DDevice9 *device)
5827 {
5828     DWORD shader_sge_vec_code[] = {
5829         0xfffe0101,                                         /* vs_1_1                   */
5830         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5831         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5832         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5833         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5834         0x0000ffff                                          /* end                      */
5835     };
5836     DWORD shader_slt_vec_code[] = {
5837         0xfffe0101,                                         /* vs_1_1                   */
5838         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5839         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5840         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5841         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5842         0x0000ffff                                          /* end                      */
5843     };
5844     DWORD shader_sge_scalar_code[] = {
5845         0xfffe0101,                                         /* vs_1_1                   */
5846         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5847         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5848         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5849         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5850         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5851         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5852         0x0000ffff                                          /* end                      */
5853     };
5854     DWORD shader_slt_scalar_code[] = {
5855         0xfffe0101,                                         /* vs_1_1                   */
5856         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5857         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5858         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5859         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5860         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5861         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5862         0x0000ffff                                          /* end                      */
5863     };
5864     IDirect3DVertexShader9 *shader_sge_vec;
5865     IDirect3DVertexShader9 *shader_slt_vec;
5866     IDirect3DVertexShader9 *shader_sge_scalar;
5867     IDirect3DVertexShader9 *shader_slt_scalar;
5868     HRESULT hr, color;
5869     float quad1[] =  {
5870         -1.0,   -1.0,   0.1,
5871          0.0,   -1.0,   0.1,
5872         -1.0,    0.0,   0.1,
5873          0.0,    0.0,   0.1
5874     };
5875     float quad2[] =  {
5876          0.0,   -1.0,   0.1,
5877          1.0,   -1.0,   0.1,
5878          0.0,    0.0,   0.1,
5879          1.0,    0.0,   0.1
5880     };
5881     float quad3[] =  {
5882         -1.0,    0.0,   0.1,
5883          0.0,    0.0,   0.1,
5884         -1.0,    1.0,   0.1,
5885          0.0,    1.0,   0.1
5886     };
5887     float quad4[] =  {
5888          0.0,    0.0,   0.1,
5889          1.0,    0.0,   0.1,
5890          0.0,    1.0,   0.1,
5891          1.0,    1.0,   0.1
5892     };
5893     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5894     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5895
5896     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5897
5898     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5899     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5900     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5901     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5902     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5903     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5904     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5905     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5906     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5907     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5908     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5909     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5910     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5911     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5912
5913     hr = IDirect3DDevice9_BeginScene(device);
5914     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5915     if(SUCCEEDED(hr))
5916     {
5917         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5918         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5920         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5921
5922         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5923         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5925         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5926
5927         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5928         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5929         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5930         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5931
5932         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5933         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5934
5935         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5936         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5939
5940         hr = IDirect3DDevice9_EndScene(device);
5941         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5942     }
5943
5944     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5945     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5946     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5947     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5948
5949     color = getPixelColor(device, 160, 360);
5950     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5951     color = getPixelColor(device, 480, 360);
5952     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5953     color = getPixelColor(device, 160, 120);
5954     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5955     color = getPixelColor(device, 480, 160);
5956     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5957
5958     IDirect3DVertexShader9_Release(shader_sge_vec);
5959     IDirect3DVertexShader9_Release(shader_slt_vec);
5960     IDirect3DVertexShader9_Release(shader_sge_scalar);
5961     IDirect3DVertexShader9_Release(shader_slt_scalar);
5962 }
5963
5964 static void test_vshader_input(IDirect3DDevice9 *device)
5965 {
5966     DWORD swapped_shader_code_3[] = {
5967         0xfffe0300,                                         /* vs_3_0               */
5968         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5969         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5970         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5971         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5972         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5973         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5974         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5975         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5976         0x0000ffff                                          /* end                  */
5977     };
5978     DWORD swapped_shader_code_1[] = {
5979         0xfffe0101,                                         /* vs_1_1               */
5980         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5981         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5982         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5983         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5984         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5985         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5986         0x0000ffff                                          /* end                  */
5987     };
5988     DWORD swapped_shader_code_2[] = {
5989         0xfffe0200,                                         /* vs_2_0               */
5990         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5991         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5992         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5993         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5994         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5995         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5996         0x0000ffff                                          /* end                  */
5997     };
5998     DWORD texcoord_color_shader_code_3[] = {
5999         0xfffe0300,                                         /* vs_3_0               */
6000         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6001         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6002         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6003         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6004         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6005         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6006         0x0000ffff                                          /* end                  */
6007     };
6008     DWORD texcoord_color_shader_code_2[] = {
6009         0xfffe0200,                                         /* vs_2_0               */
6010         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6011         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6012         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6013         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6014         0x0000ffff                                          /* end                  */
6015     };
6016     DWORD texcoord_color_shader_code_1[] = {
6017         0xfffe0101,                                         /* vs_1_1               */
6018         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6019         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6020         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6021         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6022         0x0000ffff                                          /* end                  */
6023     };
6024     DWORD color_color_shader_code_3[] = {
6025         0xfffe0300,                                         /* vs_3_0               */
6026         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6027         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6028         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6029         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6030         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6031         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6032         0x0000ffff                                          /* end                  */
6033     };
6034     DWORD color_color_shader_code_2[] = {
6035         0xfffe0200,                                         /* vs_2_0               */
6036         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6037         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6038         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6039         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6040         0x0000ffff                                          /* end                  */
6041     };
6042     DWORD color_color_shader_code_1[] = {
6043         0xfffe0101,                                         /* vs_1_1               */
6044         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6045         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6046         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6047         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6048         0x0000ffff                                          /* end                  */
6049     };
6050     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6051     HRESULT hr;
6052     DWORD color;
6053     float quad1[] =  {
6054         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6055          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6056         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6057          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6058     };
6059     float quad2[] =  {
6060          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6061          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6062          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6063          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6064     };
6065     float quad3[] =  {
6066         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6067          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6068         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6069          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6070     };
6071     float quad4[] =  {
6072          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6073          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6074          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6075          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6076     };
6077     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6078         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6079         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6080         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6081         D3DDECL_END()
6082     };
6083     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6084         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6085         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6086         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6087         D3DDECL_END()
6088     };
6089     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6090         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6091         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6092         D3DDECL_END()
6093     };
6094     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6095         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6096         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6097         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6098         D3DDECL_END()
6099     };
6100     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6101         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6102         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6103         D3DDECL_END()
6104     };
6105     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6106         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6107         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6108         D3DDECL_END()
6109     };
6110     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6111         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6112         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6113         D3DDECL_END()
6114     };
6115     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6116         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6117         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6118         D3DDECL_END()
6119     };
6120     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6121     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6122     unsigned int i;
6123     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6124     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6125
6126     struct vertex quad1_color[] =  {
6127        {-1.0,   -1.0,   0.1,    0x00ff8040},
6128        { 0.0,   -1.0,   0.1,    0x00ff8040},
6129        {-1.0,    0.0,   0.1,    0x00ff8040},
6130        { 0.0,    0.0,   0.1,    0x00ff8040}
6131     };
6132     struct vertex quad2_color[] =  {
6133        { 0.0,   -1.0,   0.1,    0x00ff8040},
6134        { 1.0,   -1.0,   0.1,    0x00ff8040},
6135        { 0.0,    0.0,   0.1,    0x00ff8040},
6136        { 1.0,    0.0,   0.1,    0x00ff8040}
6137     };
6138     struct vertex quad3_color[] =  {
6139        {-1.0,    0.0,   0.1,    0x00ff8040},
6140        { 0.0,    0.0,   0.1,    0x00ff8040},
6141        {-1.0,    1.0,   0.1,    0x00ff8040},
6142        { 0.0,    1.0,   0.1,    0x00ff8040}
6143     };
6144     float quad4_color[] =  {
6145          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6146          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6147          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6148          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6149     };
6150
6151     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6152     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6153     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6154     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6155     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6156     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6157     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6158     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6159
6160     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6161     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6162     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6163     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6164     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6165     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6166     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6167     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6168
6169     for(i = 1; i <= 3; i++) {
6170         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6171         if(i == 3) {
6172             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6173             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6174         } else if(i == 2){
6175             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6176             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6177         } else if(i == 1) {
6178             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6179             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6180         }
6181
6182         hr = IDirect3DDevice9_BeginScene(device);
6183         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6184         if(SUCCEEDED(hr))
6185         {
6186             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6187             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6188
6189             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6190             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6191             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6192             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6193
6194             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6195             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6196             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6197             if(i == 3 || i == 2) {
6198                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6199             } else if(i == 1) {
6200                 /* Succeeds or fails, depending on SW or HW vertex processing */
6201                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6202             }
6203
6204             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6205             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6206             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6207             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6208
6209             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6210             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6211             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6212             if(i == 3 || i == 2) {
6213                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6214             } else if(i == 1) {
6215                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6216             }
6217
6218             hr = IDirect3DDevice9_EndScene(device);
6219             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6220         }
6221
6222         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6223         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6224
6225         if(i == 3 || i == 2) {
6226             color = getPixelColor(device, 160, 360);
6227             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6228                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6229
6230             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6231             color = getPixelColor(device, 480, 360);
6232             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6233                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6234             color = getPixelColor(device, 160, 120);
6235             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6236             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6237                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6238
6239             color = getPixelColor(device, 480, 160);
6240             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6241         } else if(i == 1) {
6242             color = getPixelColor(device, 160, 360);
6243             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6244                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6245             color = getPixelColor(device, 480, 360);
6246             /* Accept the clear color as well in this case, since SW VP returns an error */
6247             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6248             color = getPixelColor(device, 160, 120);
6249             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6250                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6251             color = getPixelColor(device, 480, 160);
6252             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6253         }
6254
6255         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6256         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6257
6258         /* Now find out if the whole streams are re-read, or just the last active value for the
6259          * vertices is used.
6260          */
6261         hr = IDirect3DDevice9_BeginScene(device);
6262         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6263         if(SUCCEEDED(hr))
6264         {
6265             float quad1_modified[] =  {
6266                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6267                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6268                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6269                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6270             };
6271             float quad2_modified[] =  {
6272                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6273                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6274                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6275                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6276             };
6277
6278             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6279             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6280
6281             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6282             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6283             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6284             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6285
6286             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6287             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6288             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6289             if(i == 3 || i == 2) {
6290                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6291             } else if(i == 1) {
6292                 /* Succeeds or fails, depending on SW or HW vertex processing */
6293                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6294             }
6295
6296             hr = IDirect3DDevice9_EndScene(device);
6297             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6298         }
6299         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6300         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6301
6302         color = getPixelColor(device, 480, 350);
6303         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6304          * as well.
6305          *
6306          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6307          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6308          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6309          * refrast's result.
6310          *
6311          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6312          */
6313         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6314            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6315         color = getPixelColor(device, 160, 120);
6316
6317         IDirect3DDevice9_SetVertexShader(device, NULL);
6318         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6319
6320         IDirect3DVertexShader9_Release(swapped_shader);
6321     }
6322
6323     for(i = 1; i <= 3; i++) {
6324         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6325         if(i == 3) {
6326             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6327             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6328             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6329             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6330         } else if(i == 2){
6331             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6332             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6333             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6334             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6335         } else if(i == 1) {
6336             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6337             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6338             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6339             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6340         }
6341
6342         hr = IDirect3DDevice9_BeginScene(device);
6343         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6344         if(SUCCEEDED(hr))
6345         {
6346             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6347             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6348             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6349             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6350             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6351             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6352
6353             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6354             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6355
6356             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6357             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6358             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6359             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6360             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6361             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6362
6363             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6364             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6365             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6366             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6367             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6368             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6369
6370             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6371             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6372             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6373             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6374
6375             hr = IDirect3DDevice9_EndScene(device);
6376             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6377         }
6378         IDirect3DDevice9_SetVertexShader(device, NULL);
6379         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6380
6381         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6382         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6383
6384         color = getPixelColor(device, 160, 360);
6385         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6386            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6387         color = getPixelColor(device, 480, 360);
6388         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6389            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6390         color = getPixelColor(device, 160, 120);
6391         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6392            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6393         color = getPixelColor(device, 480, 160);
6394         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6395            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6396
6397         IDirect3DVertexShader9_Release(texcoord_color_shader);
6398         IDirect3DVertexShader9_Release(color_color_shader);
6399     }
6400
6401     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6402     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6403     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6404     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6405
6406     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6407     IDirect3DVertexDeclaration9_Release(decl_color_color);
6408     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6409     IDirect3DVertexDeclaration9_Release(decl_color_float);
6410 }
6411
6412 static void srgbtexture_test(IDirect3DDevice9 *device)
6413 {
6414     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6415      * texture stage state to render a quad using that texture.  The resulting
6416      * color components should be 0x36 (~ 0.21), per this formula:
6417      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6418      * This is true where srgb_color > 0.04045.
6419      */
6420     IDirect3D9 *d3d = NULL;
6421     HRESULT hr;
6422     LPDIRECT3DTEXTURE9 texture = NULL;
6423     LPDIRECT3DSURFACE9 surface = NULL;
6424     D3DLOCKED_RECT lr;
6425     DWORD color;
6426     float quad[] = {
6427         -1.0,       1.0,       0.0,     0.0,    0.0,
6428          1.0,       1.0,       0.0,     1.0,    0.0,
6429         -1.0,      -1.0,       0.0,     0.0,    1.0,
6430          1.0,      -1.0,       0.0,     1.0,    1.0,
6431     };
6432
6433
6434     memset(&lr, 0, sizeof(lr));
6435     IDirect3DDevice9_GetDirect3D(device, &d3d);
6436     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6437                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6438                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6439         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6440         goto out;
6441     }
6442
6443     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6444                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6445                                         &texture, NULL);
6446     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6447     if(!texture) {
6448         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6449         goto out;
6450     }
6451     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6452     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6453
6454     fill_surface(surface, 0xff7f7f7f);
6455     IDirect3DSurface9_Release(surface);
6456
6457     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6458     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6459     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6460     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6461
6462     hr = IDirect3DDevice9_BeginScene(device);
6463     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6464     if(SUCCEEDED(hr))
6465     {
6466         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6467         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6468
6469         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6470         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6471
6472
6473         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6474         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6475
6476         hr = IDirect3DDevice9_EndScene(device);
6477         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6478     }
6479
6480     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6481     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6482     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6483     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6484
6485     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6486     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6487
6488     color = getPixelColor(device, 320, 240);
6489     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6490
6491 out:
6492     if(texture) IDirect3DTexture9_Release(texture);
6493     IDirect3D9_Release(d3d);
6494 }
6495
6496 static void shademode_test(IDirect3DDevice9 *device)
6497 {
6498     /* Render a quad and try all of the different fixed function shading models. */
6499     HRESULT hr;
6500     DWORD color0, color1;
6501     DWORD color0_gouraud = 0, color1_gouraud = 0;
6502     DWORD shademode = D3DSHADE_FLAT;
6503     DWORD primtype = D3DPT_TRIANGLESTRIP;
6504     LPVOID data = NULL;
6505     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6506     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6507     UINT i, j;
6508     struct vertex quad_strip[] =
6509     {
6510         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6511         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6512         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6513         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6514     };
6515     struct vertex quad_list[] =
6516     {
6517         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6518         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6519         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6520
6521         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6522         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6523         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6524     };
6525
6526     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6527                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6528     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6529     if (FAILED(hr)) goto bail;
6530
6531     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6532                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6533     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6534     if (FAILED(hr)) goto bail;
6535
6536     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6537     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6538
6539     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6540     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6541
6542     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6543     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6544     memcpy(data, quad_strip, sizeof(quad_strip));
6545     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6546     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6547
6548     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6549     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6550     memcpy(data, quad_list, sizeof(quad_list));
6551     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6552     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6553
6554     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6555      * the color fixups we have to do for FLAT shading will be dependent on that. */
6556     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6557     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6558
6559     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6560     for (j=0; j<2; j++) {
6561
6562         /* Inner loop just changes the D3DRS_SHADEMODE */
6563         for (i=0; i<3; i++) {
6564             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6565             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6566
6567             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6568             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6569
6570             hr = IDirect3DDevice9_BeginScene(device);
6571             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6572             if(SUCCEEDED(hr))
6573             {
6574                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6575                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6576
6577                 hr = IDirect3DDevice9_EndScene(device);
6578                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6579             }
6580
6581             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6582             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6583
6584             /* Sample two spots from the output */
6585             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6586             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6587             switch(shademode) {
6588                 case D3DSHADE_FLAT:
6589                     /* Should take the color of the first vertex of each triangle */
6590                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6591                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6592                     shademode = D3DSHADE_GOURAUD;
6593                     break;
6594                 case D3DSHADE_GOURAUD:
6595                     /* Should be an interpolated blend */
6596
6597                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6598                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6599                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6600                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6601
6602                     color0_gouraud = color0;
6603                     color1_gouraud = color1;
6604
6605                     shademode = D3DSHADE_PHONG;
6606                     break;
6607                 case D3DSHADE_PHONG:
6608                     /* Should be the same as GOURAUD, since no hardware implements this */
6609                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6610                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6611                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6612                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6613
6614                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6615                             color0_gouraud, color0);
6616                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6617                             color1_gouraud, color1);
6618                     break;
6619             }
6620         }
6621         /* Now, do it all over again with a TRIANGLELIST */
6622         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6623         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6624         primtype = D3DPT_TRIANGLELIST;
6625         shademode = D3DSHADE_FLAT;
6626     }
6627
6628 bail:
6629     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6630     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6633
6634     if (vb_strip)
6635         IDirect3DVertexBuffer9_Release(vb_strip);
6636     if (vb_list)
6637         IDirect3DVertexBuffer9_Release(vb_list);
6638 }
6639
6640
6641 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6642 {
6643     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6644      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6645      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6646      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6647      * 0.73
6648      *
6649      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6650      * so use shaders for this task
6651      */
6652     IDirect3DPixelShader9 *pshader;
6653     IDirect3DVertexShader9 *vshader;
6654     IDirect3D9 *d3d;
6655     DWORD vshader_code[] = {
6656         0xfffe0101,                                                             /* vs_1_1                       */
6657         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6658         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6659         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6660         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6661         0x0000ffff                                                              /* end                          */
6662     };
6663     DWORD pshader_code[] = {
6664         0xffff0101,                                                             /* ps_1_1                       */
6665         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6666         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6667         0x0000ffff                                                              /* end                          */
6668     };
6669     const float quad[] = {
6670        -1.0,   -1.0,    0.1,
6671         1.0,   -1.0,    0.1,
6672        -1.0,    1.0,    0.1,
6673         1.0,    1.0,    0.1
6674     };
6675     HRESULT hr;
6676     D3DCOLOR color;
6677
6678     IDirect3DDevice9_GetDirect3D(device, &d3d);
6679     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6680      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6681      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6682      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6683      * works
6684      */
6685     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6686                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6687                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6688         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6689         IDirect3D9_Release(d3d);
6690         return;
6691     }
6692     IDirect3D9_Release(d3d);
6693
6694     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6695     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6696
6697     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6698     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6699     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6700     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6701     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6702     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6703     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6704     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6706     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6707
6708     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6709     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6710     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6711     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6712     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6713     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6714     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6715     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6716     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6717     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6718
6719     hr = IDirect3DDevice9_BeginScene(device);
6720     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6721     if(SUCCEEDED(hr)) {
6722         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6723         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6724
6725         hr = IDirect3DDevice9_EndScene(device);
6726         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6727     }
6728
6729     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6730     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6731     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6732     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6733     IDirect3DPixelShader9_Release(pshader);
6734     IDirect3DVertexShader9_Release(vshader);
6735
6736     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6737     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6738     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6739     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6740
6741     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6742     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6743     color = getPixelColor(device, 160, 360);
6744     ok(color_match(color, 0x00808080, 1),
6745             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6746 }
6747
6748 static void alpha_test(IDirect3DDevice9 *device)
6749 {
6750     HRESULT hr;
6751     IDirect3DTexture9 *offscreenTexture;
6752     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6753     DWORD color;
6754
6755     struct vertex quad1[] =
6756     {
6757         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6758         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6759         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6760         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6761     };
6762     struct vertex quad2[] =
6763     {
6764         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6765         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6766         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6767         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6768     };
6769     static const float composite_quad[][5] = {
6770         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6771         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6772         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6773         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6774     };
6775
6776     /* Clear the render target with alpha = 0.5 */
6777     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6778     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6779
6780     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6781     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6782
6783     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6784     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6785     if(!backbuffer) {
6786         goto out;
6787     }
6788
6789     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6790     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6791     if(!offscreen) {
6792         goto out;
6793     }
6794
6795     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6796     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6797
6798     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6799     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6800     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6801     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6802     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6803     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6804     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6805     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6806     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6807     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6808
6809     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6810     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6811     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6812
6813         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6814         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6815         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6816         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6817         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6819         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6820
6821         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6822         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6823         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6824         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6825         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6826         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6827
6828         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6829          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6830          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6831         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6832         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6833         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6834         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6835
6836         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6837         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6838         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6839         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6840         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6841         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6842
6843         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6844         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6845         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6846         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6848         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6849
6850         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6851         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6852
6853         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6854          * Disable alpha blending for the final composition
6855          */
6856         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6857         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6858         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6859         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6860
6861         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6862         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6863         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6864         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6865         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6866         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6867
6868         hr = IDirect3DDevice9_EndScene(device);
6869         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6870     }
6871
6872     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6873
6874     color = getPixelColor(device, 160, 360);
6875     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6876        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6877
6878     color = getPixelColor(device, 160, 120);
6879     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6880        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6881
6882     color = getPixelColor(device, 480, 360);
6883     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6884        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6885
6886     color = getPixelColor(device, 480, 120);
6887     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6888        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6889
6890     out:
6891     /* restore things */
6892     if(backbuffer) {
6893         IDirect3DSurface9_Release(backbuffer);
6894     }
6895     if(offscreenTexture) {
6896         IDirect3DTexture9_Release(offscreenTexture);
6897     }
6898     if(offscreen) {
6899         IDirect3DSurface9_Release(offscreen);
6900     }
6901 }
6902
6903 struct vertex_shortcolor {
6904     float x, y, z;
6905     unsigned short r, g, b, a;
6906 };
6907 struct vertex_floatcolor {
6908     float x, y, z;
6909     float r, g, b, a;
6910 };
6911
6912 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6913 {
6914     HRESULT hr;
6915     BOOL s_ok, ub_ok, f_ok;
6916     DWORD color, size, i;
6917     void *data;
6918     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6919         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6920         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6921         D3DDECL_END()
6922     };
6923     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6924         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6925         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6926         D3DDECL_END()
6927     };
6928     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6929         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6930         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6931         D3DDECL_END()
6932     };
6933     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6934         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6935         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6936         D3DDECL_END()
6937     };
6938     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6939         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6940         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6941         D3DDECL_END()
6942     };
6943     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6944         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6945         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6946         D3DDECL_END()
6947     };
6948     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6949         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6950         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6951         D3DDECL_END()
6952     };
6953     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6954     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6955     IDirect3DVertexBuffer9 *vb, *vb2;
6956     struct vertex quad1[] =                             /* D3DCOLOR */
6957     {
6958         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6959         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6960         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6961         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6962     };
6963     struct vertex quad2[] =                             /* UBYTE4N */
6964     {
6965         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6966         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6967         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6968         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6969     };
6970     struct vertex_shortcolor quad3[] =                  /* short */
6971     {
6972         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6973         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6974         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6975         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6976     };
6977     struct vertex_floatcolor quad4[] =
6978     {
6979         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6980         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6981         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6982         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6983     };
6984     DWORD colors[] = {
6985         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6986         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6987         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6988         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6989         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6990         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6991         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6992         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6993         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6994         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6995         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6996         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6997         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6998         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6999         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7000         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7001     };
7002     float quads[] = {
7003         -1.0,   -1.0,     0.1,
7004         -1.0,    0.0,     0.1,
7005          0.0,   -1.0,     0.1,
7006          0.0,    0.0,     0.1,
7007
7008          0.0,   -1.0,     0.1,
7009          0.0,    0.0,     0.1,
7010          1.0,   -1.0,     0.1,
7011          1.0,    0.0,     0.1,
7012
7013          0.0,    0.0,     0.1,
7014          0.0,    1.0,     0.1,
7015          1.0,    0.0,     0.1,
7016          1.0,    1.0,     0.1,
7017
7018         -1.0,    0.0,     0.1,
7019         -1.0,    1.0,     0.1,
7020          0.0,    0.0,     0.1,
7021          0.0,    1.0,     0.1
7022     };
7023     struct tvertex quad_transformed[] = {
7024        {  90,    110,     0.1,      2.0,        0x00ffff00},
7025        { 570,    110,     0.1,      2.0,        0x00ffff00},
7026        {  90,    300,     0.1,      2.0,        0x00ffff00},
7027        { 570,    300,     0.1,      2.0,        0x00ffff00}
7028     };
7029     D3DCAPS9 caps;
7030
7031     memset(&caps, 0, sizeof(caps));
7032     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7033     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7034
7035     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7036     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7037
7038     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7039     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7040     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7041     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7042     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7043     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7044     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7045         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7046         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7047         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7048         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7049     } else {
7050         trace("D3DDTCAPS_UBYTE4N not supported\n");
7051         dcl_ubyte_2 = NULL;
7052         dcl_ubyte = NULL;
7053     }
7054     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7055     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7056     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7057     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7058
7059     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7060     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7061                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7062     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7063
7064     hr = IDirect3DDevice9_BeginScene(device);
7065     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7066     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7067     if(SUCCEEDED(hr)) {
7068         if(dcl_color) {
7069             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7070             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7071             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7072             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7073         }
7074
7075         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7076          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7077          * using software vertex processing. Doh!
7078          */
7079         if(dcl_ubyte) {
7080             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7081             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7082             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7083             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7084             ub_ok = SUCCEEDED(hr);
7085         }
7086
7087         if(dcl_short) {
7088             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7089             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7090             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7091             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7092             s_ok = SUCCEEDED(hr);
7093         }
7094
7095         if(dcl_float) {
7096             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7097             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7098             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7099             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7100             f_ok = SUCCEEDED(hr);
7101         }
7102
7103         hr = IDirect3DDevice9_EndScene(device);
7104         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7105     }
7106
7107     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7108     if(dcl_short) {
7109         color = getPixelColor(device, 480, 360);
7110         ok(color == 0x000000ff || !s_ok,
7111            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7112     }
7113     if(dcl_ubyte) {
7114         color = getPixelColor(device, 160, 120);
7115         ok(color == 0x0000ffff || !ub_ok,
7116            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7117     }
7118     if(dcl_color) {
7119         color = getPixelColor(device, 160, 360);
7120         ok(color == 0x00ffff00,
7121            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7122     }
7123     if(dcl_float) {
7124         color = getPixelColor(device, 480, 120);
7125         ok(color == 0x00ff0000 || !f_ok,
7126            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7127     }
7128
7129     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7130      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7131      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7132      * whether the immediate mode code works
7133      */
7134     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7135     hr = IDirect3DDevice9_BeginScene(device);
7136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7137     if(SUCCEEDED(hr)) {
7138         if(dcl_color) {
7139             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7140             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7141             memcpy(data, quad1, sizeof(quad1));
7142             hr = IDirect3DVertexBuffer9_Unlock(vb);
7143             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7144             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7145             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7146             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7147             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7148             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7149             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7150         }
7151
7152         if(dcl_ubyte) {
7153             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7154             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7155             memcpy(data, quad2, sizeof(quad2));
7156             hr = IDirect3DVertexBuffer9_Unlock(vb);
7157             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7158             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7159             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7161             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7162             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7163             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7164                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7165             ub_ok = SUCCEEDED(hr);
7166         }
7167
7168         if(dcl_short) {
7169             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7170             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7171             memcpy(data, quad3, sizeof(quad3));
7172             hr = IDirect3DVertexBuffer9_Unlock(vb);
7173             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7174             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7175             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7176             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7177             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7178             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7179             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7180                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7181             s_ok = SUCCEEDED(hr);
7182         }
7183
7184         if(dcl_float) {
7185             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7186             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7187             memcpy(data, quad4, sizeof(quad4));
7188             hr = IDirect3DVertexBuffer9_Unlock(vb);
7189             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7190             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7191             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7192             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7193             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7194             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7195             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7196                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7197             f_ok = SUCCEEDED(hr);
7198         }
7199
7200         hr = IDirect3DDevice9_EndScene(device);
7201         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7202     }
7203
7204     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7205     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7206     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7207     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7208
7209     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7210     if(dcl_short) {
7211         color = getPixelColor(device, 480, 360);
7212         ok(color == 0x000000ff || !s_ok,
7213            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7214     }
7215     if(dcl_ubyte) {
7216         color = getPixelColor(device, 160, 120);
7217         ok(color == 0x0000ffff || !ub_ok,
7218            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7219     }
7220     if(dcl_color) {
7221         color = getPixelColor(device, 160, 360);
7222         ok(color == 0x00ffff00,
7223            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7224     }
7225     if(dcl_float) {
7226         color = getPixelColor(device, 480, 120);
7227         ok(color == 0x00ff0000 || !f_ok,
7228            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7229     }
7230
7231     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7232     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7233
7234     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7235     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7236     memcpy(data, quad_transformed, sizeof(quad_transformed));
7237     hr = IDirect3DVertexBuffer9_Unlock(vb);
7238     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7239
7240     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7241     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7242
7243     hr = IDirect3DDevice9_BeginScene(device);
7244     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7245     if(SUCCEEDED(hr)) {
7246         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7247         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7248         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7249         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7250
7251         hr = IDirect3DDevice9_EndScene(device);
7252         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7253     }
7254
7255     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7256     color = getPixelColor(device, 88, 108);
7257     ok(color == 0x000000ff,
7258        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7259     color = getPixelColor(device, 92, 108);
7260     ok(color == 0x000000ff,
7261        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7262     color = getPixelColor(device, 88, 112);
7263     ok(color == 0x000000ff,
7264        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7265     color = getPixelColor(device, 92, 112);
7266     ok(color == 0x00ffff00,
7267        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7268
7269     color = getPixelColor(device, 568, 108);
7270     ok(color == 0x000000ff,
7271        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7272     color = getPixelColor(device, 572, 108);
7273     ok(color == 0x000000ff,
7274        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7275     color = getPixelColor(device, 568, 112);
7276     ok(color == 0x00ffff00,
7277        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7278     color = getPixelColor(device, 572, 112);
7279     ok(color == 0x000000ff,
7280        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7281
7282     color = getPixelColor(device, 88, 298);
7283     ok(color == 0x000000ff,
7284        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7285     color = getPixelColor(device, 92, 298);
7286     ok(color == 0x00ffff00,
7287        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7288     color = getPixelColor(device, 88, 302);
7289     ok(color == 0x000000ff,
7290        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7291     color = getPixelColor(device, 92, 302);
7292     ok(color == 0x000000ff,
7293        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7294
7295     color = getPixelColor(device, 568, 298);
7296     ok(color == 0x00ffff00,
7297        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7298     color = getPixelColor(device, 572, 298);
7299     ok(color == 0x000000ff,
7300        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7301     color = getPixelColor(device, 568, 302);
7302     ok(color == 0x000000ff,
7303        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7304     color = getPixelColor(device, 572, 302);
7305     ok(color == 0x000000ff,
7306        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7307
7308     /* This test is pointless without those two declarations: */
7309     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7310         skip("color-ubyte switching test declarations aren't supported\n");
7311         goto out;
7312     }
7313
7314     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7315     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7316     memcpy(data, quads, sizeof(quads));
7317     hr = IDirect3DVertexBuffer9_Unlock(vb);
7318     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7319     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7320                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7321     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7322     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7323     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7324     memcpy(data, colors, sizeof(colors));
7325     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7326     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7327
7328     for(i = 0; i < 2; i++) {
7329         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7330         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7331
7332         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7333         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7334         if(i == 0) {
7335             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7336         } else {
7337             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7338         }
7339         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7340
7341         hr = IDirect3DDevice9_BeginScene(device);
7342         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7343         ub_ok = FALSE;
7344         if(SUCCEEDED(hr)) {
7345             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7346             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7347             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7348             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7349                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7350             ub_ok = SUCCEEDED(hr);
7351
7352             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7353             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7354             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7355             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7356
7357             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7358             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7359             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7360             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7361                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7362             ub_ok = (SUCCEEDED(hr) && ub_ok);
7363
7364             hr = IDirect3DDevice9_EndScene(device);
7365             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7366         }
7367
7368         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7369         if(i == 0) {
7370             color = getPixelColor(device, 480, 360);
7371             ok(color == 0x00ff0000,
7372                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7373             color = getPixelColor(device, 160, 120);
7374             ok(color == 0x00ffffff,
7375                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7376             color = getPixelColor(device, 160, 360);
7377             ok(color == 0x000000ff || !ub_ok,
7378                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7379             color = getPixelColor(device, 480, 120);
7380             ok(color == 0x000000ff || !ub_ok,
7381                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7382         } else {
7383             color = getPixelColor(device, 480, 360);
7384             ok(color == 0x000000ff,
7385                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7386             color = getPixelColor(device, 160, 120);
7387             ok(color == 0x00ffffff,
7388                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7389             color = getPixelColor(device, 160, 360);
7390             ok(color == 0x00ff0000 || !ub_ok,
7391                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7392             color = getPixelColor(device, 480, 120);
7393             ok(color == 0x00ff0000 || !ub_ok,
7394                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7395         }
7396     }
7397
7398     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7399     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7400     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7401     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7402     IDirect3DVertexBuffer9_Release(vb2);
7403
7404     out:
7405     IDirect3DVertexBuffer9_Release(vb);
7406     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7407     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7408     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7409     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7410     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7411     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7412     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7413 }
7414
7415 struct vertex_float16color {
7416     float x, y, z;
7417     DWORD c1, c2;
7418 };
7419
7420 static void test_vshader_float16(IDirect3DDevice9 *device)
7421 {
7422     HRESULT hr;
7423     DWORD color;
7424     void *data;
7425     static const D3DVERTEXELEMENT9 decl_elements[] = {
7426         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7427         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7428         D3DDECL_END()
7429     };
7430     IDirect3DVertexDeclaration9 *vdecl = NULL;
7431     IDirect3DVertexBuffer9 *buffer = NULL;
7432     IDirect3DVertexShader9 *shader;
7433     DWORD shader_code[] = {
7434         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7435         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7436         0x90e40001, 0x0000ffff
7437     };
7438     struct vertex_float16color quad[] = {
7439         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7440         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7441         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7442         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7443
7444         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7445         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7446         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7447         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7448
7449         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7450         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7451         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7452         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7453
7454         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7455         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7456         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7457         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7458     };
7459
7460     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7461     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7462
7463     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7464     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7465     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7466     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7467     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7468     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7469
7470     hr = IDirect3DDevice9_BeginScene(device);
7471     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7472     if(SUCCEEDED(hr)) {
7473         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7474         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7475         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7476         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7477         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7478         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7480         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7482         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7483
7484         hr = IDirect3DDevice9_EndScene(device);
7485         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7486     }
7487     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7488     color = getPixelColor(device, 480, 360);
7489     ok(color == 0x00ff0000,
7490        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7491     color = getPixelColor(device, 160, 120);
7492     ok(color == 0x00000000,
7493        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7494     color = getPixelColor(device, 160, 360);
7495     ok(color == 0x0000ff00,
7496        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7497     color = getPixelColor(device, 480, 120);
7498     ok(color == 0x000000ff,
7499        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7500
7501     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7502     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7503
7504     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7505                                              D3DPOOL_MANAGED, &buffer, NULL);
7506     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7507     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7508     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7509     memcpy(data, quad, sizeof(quad));
7510     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7511     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7512     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7513     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7514
7515     hr = IDirect3DDevice9_BeginScene(device);
7516     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7517     if(SUCCEEDED(hr)) {
7518             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7519             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7520             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7521             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7522             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7523             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7524             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7525             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7526
7527             hr = IDirect3DDevice9_EndScene(device);
7528             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7529     }
7530
7531     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7532     color = getPixelColor(device, 480, 360);
7533     ok(color == 0x00ff0000,
7534        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7535     color = getPixelColor(device, 160, 120);
7536     ok(color == 0x00000000,
7537        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7538     color = getPixelColor(device, 160, 360);
7539     ok(color == 0x0000ff00,
7540        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7541     color = getPixelColor(device, 480, 120);
7542     ok(color == 0x000000ff,
7543        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7544
7545     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7546     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7547     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7548     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7549     IDirect3DDevice9_SetVertexShader(device, NULL);
7550     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7551
7552     IDirect3DVertexDeclaration9_Release(vdecl);
7553     IDirect3DVertexShader9_Release(shader);
7554     IDirect3DVertexBuffer9_Release(buffer);
7555 }
7556
7557 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7558 {
7559     D3DCAPS9 caps;
7560     IDirect3DTexture9 *texture;
7561     HRESULT hr;
7562     D3DLOCKED_RECT rect;
7563     unsigned int x, y;
7564     DWORD *dst, color;
7565     const float quad[] = {
7566         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7567          1.0,   -1.0,   0.1,    1.2,   -0.2,
7568         -1.0,    1.0,   0.1,   -0.2,    1.2,
7569          1.0,    1.0,   0.1,    1.2,    1.2
7570     };
7571     memset(&caps, 0, sizeof(caps));
7572
7573     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7574     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7575     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7576         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7577         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7578            "Card has conditional NP2 support without power of two restriction set\n");
7579         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7580         return;
7581     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7582         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7583         return;
7584     }
7585
7586     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7587     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7588
7589     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7590     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7591
7592     memset(&rect, 0, sizeof(rect));
7593     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7594     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7595     for(y = 0; y < 10; y++) {
7596         for(x = 0; x < 10; x++) {
7597             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7598             if(x == 0 || x == 9 || y == 0 || y == 9) {
7599                 *dst = 0x00ff0000;
7600             } else {
7601                 *dst = 0x000000ff;
7602             }
7603         }
7604     }
7605     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7606     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7607
7608     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7609     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7610     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7611     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7612     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7613     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7614     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7615     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7616
7617     hr = IDirect3DDevice9_BeginScene(device);
7618     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7619     if(SUCCEEDED(hr)) {
7620         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7621         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7622
7623         hr = IDirect3DDevice9_EndScene(device);
7624         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7625     }
7626
7627     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7628
7629     color = getPixelColor(device,    1,  1);
7630     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7631     color = getPixelColor(device, 639, 479);
7632     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7633
7634     color = getPixelColor(device, 135, 101);
7635     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7636     color = getPixelColor(device, 140, 101);
7637     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7638     color = getPixelColor(device, 135, 105);
7639     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7640     color = getPixelColor(device, 140, 105);
7641     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7642
7643     color = getPixelColor(device, 135, 376);
7644     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7645     color = getPixelColor(device, 140, 376);
7646     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7647     color = getPixelColor(device, 135, 379);
7648     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7649     color = getPixelColor(device, 140, 379);
7650     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7651
7652     color = getPixelColor(device, 500, 101);
7653     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7654     color = getPixelColor(device, 504, 101);
7655     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7656     color = getPixelColor(device, 500, 105);
7657     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7658     color = getPixelColor(device, 504, 105);
7659     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7660
7661     color = getPixelColor(device, 500, 376);
7662     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7663     color = getPixelColor(device, 504, 376);
7664     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7665     color = getPixelColor(device, 500, 380);
7666     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7667     color = getPixelColor(device, 504, 380);
7668     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7669
7670     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7671     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7672     IDirect3DTexture9_Release(texture);
7673 }
7674
7675 static void vFace_register_test(IDirect3DDevice9 *device)
7676 {
7677     HRESULT hr;
7678     DWORD color;
7679     const DWORD shader_code[] = {
7680         0xffff0300,                                                             /* ps_3_0                     */
7681         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7682         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7683         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7684         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7685         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7686         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7687         0x0000ffff                                                              /* END                        */
7688     };
7689     IDirect3DPixelShader9 *shader;
7690     IDirect3DTexture9 *texture;
7691     IDirect3DSurface9 *surface, *backbuffer;
7692     const float quad[] = {
7693         -1.0,   -1.0,   0.1,
7694          1.0,   -1.0,   0.1,
7695         -1.0,    0.0,   0.1,
7696
7697          1.0,   -1.0,   0.1,
7698          1.0,    0.0,   0.1,
7699         -1.0,    0.0,   0.1,
7700
7701         -1.0,    0.0,   0.1,
7702         -1.0,    1.0,   0.1,
7703          1.0,    0.0,   0.1,
7704
7705          1.0,    0.0,   0.1,
7706         -1.0,    1.0,   0.1,
7707          1.0,    1.0,   0.1,
7708     };
7709     const float blit[] = {
7710          0.0,   -1.0,   0.1,    0.0,    0.0,
7711          1.0,   -1.0,   0.1,    1.0,    0.0,
7712          0.0,    1.0,   0.1,    0.0,    1.0,
7713          1.0,    1.0,   0.1,    1.0,    1.0,
7714     };
7715
7716     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7717     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7718     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7719     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7720     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7721     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7722     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7723     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7724     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7725     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7726     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7727     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7728
7729     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7730     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7731
7732     hr = IDirect3DDevice9_BeginScene(device);
7733     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7734     if(SUCCEEDED(hr)) {
7735         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7736         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7737         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7738         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7739         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7740         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7741         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7742         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7743         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7744         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7745         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7746
7747         /* Blit the texture onto the back buffer to make it visible */
7748         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7749         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7750         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7751         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7752         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7753         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7754         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7755         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7756         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7757         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7758
7759         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7760         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7761
7762         hr = IDirect3DDevice9_EndScene(device);
7763         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7764     }
7765
7766     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7767     color = getPixelColor(device, 160, 360);
7768     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7769     color = getPixelColor(device, 160, 120);
7770     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7771     color = getPixelColor(device, 480, 360);
7772     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7773     color = getPixelColor(device, 480, 120);
7774     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7775
7776     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7777     IDirect3DDevice9_SetTexture(device, 0, NULL);
7778     IDirect3DPixelShader9_Release(shader);
7779     IDirect3DSurface9_Release(surface);
7780     IDirect3DSurface9_Release(backbuffer);
7781     IDirect3DTexture9_Release(texture);
7782 }
7783
7784 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7785 {
7786     HRESULT hr;
7787     DWORD color;
7788     int i;
7789     D3DCAPS9 caps;
7790     BOOL L6V5U5_supported = FALSE;
7791     IDirect3DTexture9 *tex1, *tex2;
7792     D3DLOCKED_RECT locked_rect;
7793
7794     static const float quad[][7] = {
7795         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7796         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7797         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7798         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7799     };
7800
7801     static const D3DVERTEXELEMENT9 decl_elements[] = {
7802         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7803         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7804         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7805         D3DDECL_END()
7806     };
7807
7808     /* use asymmetric matrix to test loading */
7809     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7810     float scale, offset;
7811
7812     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7813     IDirect3DTexture9           *texture            = NULL;
7814
7815     memset(&caps, 0, sizeof(caps));
7816     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7817     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7818     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7819         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7820         return;
7821     } else {
7822         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7823          * They report that it is not supported, but after that bump mapping works properly. So just test
7824          * if the format is generally supported, and check the BUMPENVMAP flag
7825          */
7826         IDirect3D9 *d3d9;
7827
7828         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7829         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7830                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7831         L6V5U5_supported = SUCCEEDED(hr);
7832         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7833                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7834         IDirect3D9_Release(d3d9);
7835         if(FAILED(hr)) {
7836             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7837             return;
7838         }
7839     }
7840
7841     /* Generate the textures */
7842     generate_bumpmap_textures(device);
7843
7844     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7845     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7846     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7847     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7848     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7849     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7850     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7851     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7852
7853     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7854     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7855     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7856     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7857     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7858     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7859
7860     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7861     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7862     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7863     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7864     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7865     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7866
7867     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7868     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7869
7870     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7871     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7872
7873     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7874     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7875
7876
7877     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7878     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7879     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7880     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7881
7882     hr = IDirect3DDevice9_BeginScene(device);
7883     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7884
7885     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7886     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7887
7888     hr = IDirect3DDevice9_EndScene(device);
7889     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7890
7891     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7892     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7893
7894     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7895      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7896      * But since testing the color match is not the purpose of the test don't be too picky
7897      */
7898     color = getPixelColor(device, 320-32, 240);
7899     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7900     color = getPixelColor(device, 320+32, 240);
7901     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7902     color = getPixelColor(device, 320, 240-32);
7903     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7904     color = getPixelColor(device, 320, 240+32);
7905     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7906     color = getPixelColor(device, 320, 240);
7907     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7908     color = getPixelColor(device, 320+32, 240+32);
7909     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7910     color = getPixelColor(device, 320-32, 240+32);
7911     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7912     color = getPixelColor(device, 320+32, 240-32);
7913     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7914     color = getPixelColor(device, 320-32, 240-32);
7915     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7916
7917     for(i = 0; i < 2; i++) {
7918         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7919         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7920         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7921         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7922         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7923         IDirect3DTexture9_Release(texture); /* To destroy it */
7924     }
7925
7926     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7927         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7928         goto cleanup;
7929     }
7930     if(L6V5U5_supported == FALSE) {
7931         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7932         goto cleanup;
7933     }
7934
7935     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7936     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7937     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7938      * would only make this test more complicated
7939      */
7940     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7941     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7942     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7943     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7944
7945     memset(&locked_rect, 0, sizeof(locked_rect));
7946     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7947     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7948     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7949     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7950     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7951
7952     memset(&locked_rect, 0, sizeof(locked_rect));
7953     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7954     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7955     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7956     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7957     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7958
7959     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7960     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7961     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7962     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7963
7964     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7965     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7966     scale = 2.0;
7967     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7968     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7969     offset = 0.1;
7970     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7971     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7972
7973     hr = IDirect3DDevice9_BeginScene(device);
7974     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7975     if(SUCCEEDED(hr)) {
7976         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7977         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7978         hr = IDirect3DDevice9_EndScene(device);
7979         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7980     }
7981
7982     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7983     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7984     color = getPixelColor(device, 320, 240);
7985     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7986      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7987      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7988      */
7989     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7990
7991     /* Check a result scale factor > 1.0 */
7992     scale = 10;
7993     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7994     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995     offset = 10;
7996     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7997     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7998
7999     hr = IDirect3DDevice9_BeginScene(device);
8000     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8001     if(SUCCEEDED(hr)) {
8002         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8003         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8004         hr = IDirect3DDevice9_EndScene(device);
8005         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8006     }
8007     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8008     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8009     color = getPixelColor(device, 320, 240);
8010     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8011
8012     /* Check clamping in the scale factor calculation */
8013     scale = 1000;
8014     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8015     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8016     offset = -1;
8017     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8018     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8019
8020     hr = IDirect3DDevice9_BeginScene(device);
8021     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8022     if(SUCCEEDED(hr)) {
8023         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8024         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8025         hr = IDirect3DDevice9_EndScene(device);
8026         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8027     }
8028     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8029     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8030     color = getPixelColor(device, 320, 240);
8031     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8032
8033     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8034     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8035     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8036     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8037
8038     IDirect3DTexture9_Release(tex1);
8039     IDirect3DTexture9_Release(tex2);
8040
8041 cleanup:
8042     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8043     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8044     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8045     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8046
8047     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8048     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8049     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8050 }
8051
8052 static void stencil_cull_test(IDirect3DDevice9 *device) {
8053     HRESULT hr;
8054     IDirect3DSurface9 *depthstencil = NULL;
8055     D3DSURFACE_DESC desc;
8056     float quad1[] = {
8057         -1.0,   -1.0,   0.1,
8058          0.0,   -1.0,   0.1,
8059         -1.0,    0.0,   0.1,
8060          0.0,    0.0,   0.1,
8061     };
8062     float quad2[] = {
8063          0.0,   -1.0,   0.1,
8064          1.0,   -1.0,   0.1,
8065          0.0,    0.0,   0.1,
8066          1.0,    0.0,   0.1,
8067     };
8068     float quad3[] = {
8069         0.0,    0.0,   0.1,
8070         1.0,    0.0,   0.1,
8071         0.0,    1.0,   0.1,
8072         1.0,    1.0,   0.1,
8073     };
8074     float quad4[] = {
8075         -1.0,    0.0,   0.1,
8076          0.0,    0.0,   0.1,
8077         -1.0,    1.0,   0.1,
8078          0.0,    1.0,   0.1,
8079     };
8080     struct vertex painter[] = {
8081        {-1.0,   -1.0,   0.0,    0x00000000},
8082        { 1.0,   -1.0,   0.0,    0x00000000},
8083        {-1.0,    1.0,   0.0,    0x00000000},
8084        { 1.0,    1.0,   0.0,    0x00000000},
8085     };
8086     WORD indices_cw[]  = {0, 1, 3};
8087     WORD indices_ccw[] = {0, 2, 3};
8088     unsigned int i;
8089     DWORD color;
8090
8091     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8092     if(depthstencil == NULL) {
8093         skip("No depth stencil buffer\n");
8094         return;
8095     }
8096     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8097     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8098     IDirect3DSurface9_Release(depthstencil);
8099     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8100         skip("No 4 or 8 bit stencil surface\n");
8101         return;
8102     }
8103
8104     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8105     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8106     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8107
8108     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8109     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8110     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8111     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8113     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8115     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8116
8117     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8118     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8119     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8120     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8121     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8122     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123
8124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128
8129     /* First pass: Fill the stencil buffer with some values... */
8130     hr = IDirect3DDevice9_BeginScene(device);
8131     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8132     if(SUCCEEDED(hr))
8133     {
8134         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8135         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8136         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8137                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8138         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8139                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8140
8141         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8142         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8143         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8144         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8145         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8146                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8147         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8148                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8149
8150         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8151         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8153                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8154         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8155                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8156
8157         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8158         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8159         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8160                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8161         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8162                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8163
8164         hr = IDirect3DDevice9_EndScene(device);
8165         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8166     }
8167
8168     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8169     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8170     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8171     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8172     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8173     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8174     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8176     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8177     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8178     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8179     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8180     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8181
8182     /* 2nd pass: Make the stencil values visible */
8183     hr = IDirect3DDevice9_BeginScene(device);
8184     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8185     if(SUCCEEDED(hr))
8186     {
8187         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8188         for(i = 0; i < 16; i++) {
8189             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8190             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8191
8192             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8193             painter[1].diffuse = (i * 16);
8194             painter[2].diffuse = (i * 16);
8195             painter[3].diffuse = (i * 16);
8196             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8197             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8198         }
8199         hr = IDirect3DDevice9_EndScene(device);
8200         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8201     }
8202
8203     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8204     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8205
8206     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8207     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8208
8209     color = getPixelColor(device, 160, 420);
8210     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8211     color = getPixelColor(device, 160, 300);
8212     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8213
8214     color = getPixelColor(device, 480, 420);
8215     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8216     color = getPixelColor(device, 480, 300);
8217     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8218
8219     color = getPixelColor(device, 160, 180);
8220     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8221     color = getPixelColor(device, 160, 60);
8222     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8223
8224     color = getPixelColor(device, 480, 180);
8225     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8226     color = getPixelColor(device, 480, 60);
8227     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8228 }
8229
8230 static void vpos_register_test(IDirect3DDevice9 *device)
8231 {
8232     HRESULT hr;
8233     DWORD color;
8234     const DWORD shader_code[] = {
8235     0xffff0300,                                                             /* ps_3_0                     */
8236     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8237     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8238     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8239     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8240     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8241     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8242     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8243     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8244     0x0000ffff                                                              /* end                        */
8245     };
8246     const DWORD shader_frac_code[] = {
8247     0xffff0300,                                                             /* ps_3_0                     */
8248     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8249     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8250     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8251     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8252     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8253     0x0000ffff                                                              /* end                        */
8254     };
8255     IDirect3DPixelShader9 *shader, *shader_frac;
8256     IDirect3DSurface9 *surface = NULL, *backbuffer;
8257     const float quad[] = {
8258         -1.0,   -1.0,   0.1,    0.0,    0.0,
8259          1.0,   -1.0,   0.1,    1.0,    0.0,
8260         -1.0,    1.0,   0.1,    0.0,    1.0,
8261          1.0,    1.0,   0.1,    1.0,    1.0,
8262     };
8263     D3DLOCKED_RECT lr;
8264     float constant[4] = {1.0, 0.0, 320, 240};
8265     DWORD *pos;
8266
8267     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8268     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8269     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8270     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8271     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8272     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8273     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8274     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8275     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8276     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8277     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8278     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8279
8280     hr = IDirect3DDevice9_BeginScene(device);
8281     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8282     if(SUCCEEDED(hr)) {
8283         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8284         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8286         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8287         hr = IDirect3DDevice9_EndScene(device);
8288         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8289     }
8290
8291     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8292     /* This has to be pixel exact */
8293     color = getPixelColor(device, 319, 239);
8294     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8295     color = getPixelColor(device, 320, 239);
8296     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8297     color = getPixelColor(device, 319, 240);
8298     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8299     color = getPixelColor(device, 320, 240);
8300     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8301
8302     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8303                                              &surface, NULL);
8304     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8305     hr = IDirect3DDevice9_BeginScene(device);
8306     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8307     if(SUCCEEDED(hr)) {
8308         constant[2] = 16; constant[3] = 16;
8309         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8310         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8311         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8312         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8313         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8314         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8315         hr = IDirect3DDevice9_EndScene(device);
8316         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8317     }
8318     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8319     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8320
8321     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8322     color = *pos & 0x00ffffff;
8323     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8324     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8325     color = *pos & 0x00ffffff;
8326     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8327     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8328     color = *pos & 0x00ffffff;
8329     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8330     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8331     color = *pos & 0x00ffffff;
8332     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8333
8334     hr = IDirect3DSurface9_UnlockRect(surface);
8335     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8336
8337     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8338      * have full control over the multisampling setting inside this test
8339      */
8340     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8341     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8342     hr = IDirect3DDevice9_BeginScene(device);
8343     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8344     if(SUCCEEDED(hr)) {
8345         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8346         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8347         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8348         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8349         hr = IDirect3DDevice9_EndScene(device);
8350         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8351     }
8352     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8353     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8354
8355     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8356     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8357
8358     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8359     color = *pos & 0x00ffffff;
8360     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8361
8362     hr = IDirect3DSurface9_UnlockRect(surface);
8363     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8364
8365     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8366     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8367     IDirect3DPixelShader9_Release(shader);
8368     IDirect3DPixelShader9_Release(shader_frac);
8369     if(surface) IDirect3DSurface9_Release(surface);
8370     IDirect3DSurface9_Release(backbuffer);
8371 }
8372
8373 static void pointsize_test(IDirect3DDevice9 *device)
8374 {
8375     HRESULT hr;
8376     D3DCAPS9 caps;
8377     D3DMATRIX matrix;
8378     D3DMATRIX identity;
8379     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8380     DWORD color;
8381     IDirect3DTexture9 *tex1, *tex2;
8382     D3DLOCKED_RECT lr;
8383     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8384                                 0x00000000, 0x00000000};
8385     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8386                                 0x00000000, 0x0000ff00};
8387
8388     const float vertices[] = {
8389         64,     64,     0.1,
8390         128,    64,     0.1,
8391         192,    64,     0.1,
8392         256,    64,     0.1,
8393         320,    64,     0.1,
8394         384,    64,     0.1,
8395         448,    64,     0.1,
8396         512,    64,     0.1,
8397         576,    64,     0.1,
8398     };
8399
8400     /* 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 */
8401     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;
8402     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;
8403     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;
8404     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;
8405
8406     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;
8407     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;
8408     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;
8409     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;
8410
8411     memset(&caps, 0, sizeof(caps));
8412     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8413     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8414     if(caps.MaxPointSize < 32.0) {
8415         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8416         return;
8417     }
8418
8419     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8420     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8421     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8422     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8423     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8424     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8425     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8426     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8427
8428     hr = IDirect3DDevice9_BeginScene(device);
8429     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8430     if(SUCCEEDED(hr)) {
8431         ptsize = 16.0;
8432         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8433         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8436
8437         ptsize = 32.0;
8438         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8439         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8440         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8441         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8442
8443         ptsize = 31.5;
8444         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8445         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8447         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8448
8449         if(caps.MaxPointSize >= 64.0) {
8450             ptsize = 64.0;
8451             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8452             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8454             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8455
8456             ptsize = 63.75;
8457             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8458             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8459             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8460             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8461         }
8462
8463         ptsize = 1.0;
8464         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8465         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8466         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8467         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468
8469         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8470         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8471         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8472         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8473
8474         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8475         ptsize = 16.0;
8476         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8477         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8478         ptsize = 1.0;
8479         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8480         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8481         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8482         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8483
8484         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8485          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8486          */
8487         ptsize = 4.0;
8488         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8489         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8490         ptsize = 16.0;
8491         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8492         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8493         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8494         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8495
8496         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8497         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8498
8499         /* pointsize < pointsize_min < pointsize_max?
8500          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8501          */
8502         ptsize = 1.0;
8503         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8504         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8505         ptsize = 16.0;
8506         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8507         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8508         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8509         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8510
8511         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8512         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8513
8514         hr = IDirect3DDevice9_EndScene(device);
8515         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8516     }
8517     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8518     color = getPixelColor(device, 64-9, 64-9);
8519     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8520     color = getPixelColor(device, 64-8, 64-8);
8521     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8522     color = getPixelColor(device, 64-7, 64-7);
8523     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8524     color = getPixelColor(device, 64+7, 64+7);
8525     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8526     color = getPixelColor(device, 64+8, 64+8);
8527     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8528     color = getPixelColor(device, 64+9, 64+9);
8529     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8530
8531     color = getPixelColor(device, 128-17, 64-17);
8532     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8533     color = getPixelColor(device, 128-16, 64-16);
8534     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8535     color = getPixelColor(device, 128-15, 64-15);
8536     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8537     color = getPixelColor(device, 128+15, 64+15);
8538     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8539     color = getPixelColor(device, 128+16, 64+16);
8540     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8541     color = getPixelColor(device, 128+17, 64+17);
8542     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8543
8544     color = getPixelColor(device, 192-17, 64-17);
8545     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8546     color = getPixelColor(device, 192-16, 64-16);
8547     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8548     color = getPixelColor(device, 192-15, 64-15);
8549     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8550     color = getPixelColor(device, 192+15, 64+15);
8551     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8552     color = getPixelColor(device, 192+16, 64+16);
8553     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8554     color = getPixelColor(device, 192+17, 64+17);
8555     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8556
8557     if(caps.MaxPointSize >= 64.0) {
8558         color = getPixelColor(device, 256-33, 64-33);
8559         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8560         color = getPixelColor(device, 256-32, 64-32);
8561         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8562         color = getPixelColor(device, 256-31, 64-31);
8563         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8564         color = getPixelColor(device, 256+31, 64+31);
8565         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8566         color = getPixelColor(device, 256+32, 64+32);
8567         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8568         color = getPixelColor(device, 256+33, 64+33);
8569         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8570
8571         color = getPixelColor(device, 384-33, 64-33);
8572         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8573         color = getPixelColor(device, 384-32, 64-32);
8574         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8575         color = getPixelColor(device, 384-31, 64-31);
8576         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8577         color = getPixelColor(device, 384+31, 64+31);
8578         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8579         color = getPixelColor(device, 384+32, 64+32);
8580         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8581         color = getPixelColor(device, 384+33, 64+33);
8582         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8583     }
8584
8585     color = getPixelColor(device, 320-1, 64-1);
8586     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8587     color = getPixelColor(device, 320-0, 64-0);
8588     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8589     color = getPixelColor(device, 320+1, 64+1);
8590     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8591
8592     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8593     color = getPixelColor(device, 448-4, 64-4);
8594     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8595     color = getPixelColor(device, 448+4, 64+4);
8596     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8597
8598     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8599     color = getPixelColor(device, 512-4, 64-4);
8600     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8601     color = getPixelColor(device, 512+4, 64+4);
8602     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8603
8604     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8605      * Don't be overly picky - just show that the point is bigger than 1 pixel
8606      */
8607     color = getPixelColor(device, 576-4, 64-4);
8608     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8609     color = getPixelColor(device, 576+4, 64+4);
8610     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8611
8612     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8613      * generates texture coordinates for the point(result: Yes, it does)
8614      *
8615      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8616      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8617      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8618      */
8619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8621
8622     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8623     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8624     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8625     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8626     memset(&lr, 0, sizeof(lr));
8627     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8628     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8629     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8630     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8631     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8632     memset(&lr, 0, sizeof(lr));
8633     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8634     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8635     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8636     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8637     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8638     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8639     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8640     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8641     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8642     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8643     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8644     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8645     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8646     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8648     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8649     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8650     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8651     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8652
8653     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8654     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8655     ptsize = 32.0;
8656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8657     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8658
8659     hr = IDirect3DDevice9_BeginScene(device);
8660     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8661     if(SUCCEEDED(hr))
8662     {
8663         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8664         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8665         hr = IDirect3DDevice9_EndScene(device);
8666         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8667     }
8668
8669     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8670     color = getPixelColor(device, 64-4, 64-4);
8671     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8672     color = getPixelColor(device, 64-4, 64+4);
8673     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8674     color = getPixelColor(device, 64+4, 64+4);
8675     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8676     color = getPixelColor(device, 64+4, 64-4);
8677     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8678
8679     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8680     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8681     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8682     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8683     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8684     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8685     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8686     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8687     IDirect3DTexture9_Release(tex1);
8688     IDirect3DTexture9_Release(tex2);
8689
8690     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8691     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8692     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8693     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8694     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8695     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8696 }
8697
8698 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8699 {
8700     HRESULT hr;
8701     IDirect3DPixelShader9 *ps;
8702     IDirect3DTexture9 *tex1, *tex2;
8703     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8704     D3DCAPS9 caps;
8705     DWORD color;
8706     DWORD shader_code[] = {
8707     0xffff0300,                                                             /* ps_3_0             */
8708     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8709     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8710     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8711     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8712     0x0000ffff                                                              /* END                */
8713     };
8714     float quad[] = {
8715        -1.0,   -1.0,    0.1,
8716         1.0,   -1.0,    0.1,
8717        -1.0,    1.0,    0.1,
8718         1.0,    1.0,    0.1,
8719     };
8720     float texquad[] = {
8721        -1.0,   -1.0,    0.1,    0.0,    0.0,
8722         0.0,   -1.0,    0.1,    1.0,    0.0,
8723        -1.0,    1.0,    0.1,    0.0,    1.0,
8724         0.0,    1.0,    0.1,    1.0,    1.0,
8725
8726         0.0,   -1.0,    0.1,    0.0,    0.0,
8727         1.0,   -1.0,    0.1,    1.0,    0.0,
8728         0.0,    1.0,    0.1,    0.0,    1.0,
8729         1.0,    1.0,    0.1,    1.0,    1.0,
8730     };
8731
8732     memset(&caps, 0, sizeof(caps));
8733     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8735     if(caps.NumSimultaneousRTs < 2) {
8736         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8737         return;
8738     }
8739
8740     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8741     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8742
8743     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8744     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8745     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8746     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8747     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8748     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8749
8750     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8751     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8752     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8753     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8754     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8755     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8756
8757     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8758     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8759     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8760     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8761     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8762     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8764     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8765
8766     hr = IDirect3DDevice9_BeginScene(device);
8767     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8768     if(SUCCEEDED(hr)) {
8769         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8770         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8771
8772         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8773         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8774         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8775         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8776         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8777         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8778         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8779         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8780
8781         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8782         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8783         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8784         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8785
8786         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8787         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8788         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8789         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8790
8791         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8792         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8793
8794         hr = IDirect3DDevice9_EndScene(device);
8795         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8796     }
8797
8798     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8799     color = getPixelColor(device, 160, 240);
8800     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8801     color = getPixelColor(device, 480, 240);
8802     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8803
8804     IDirect3DPixelShader9_Release(ps);
8805     IDirect3DTexture9_Release(tex1);
8806     IDirect3DTexture9_Release(tex2);
8807     IDirect3DSurface9_Release(surf1);
8808     IDirect3DSurface9_Release(surf2);
8809     IDirect3DSurface9_Release(backbuf);
8810 }
8811
8812 struct formats {
8813     const char *fmtName;
8814     D3DFORMAT textureFormat;
8815     DWORD resultColorBlending;
8816     DWORD resultColorNoBlending;
8817 };
8818
8819 const struct formats test_formats[] = {
8820   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8821   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8822   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8823   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8824   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8825   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8826   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8827   { NULL, 0 }
8828 };
8829
8830 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8831 {
8832     HRESULT hr;
8833     IDirect3DTexture9 *offscreenTexture = NULL;
8834     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8835     IDirect3D9 *d3d = NULL;
8836     DWORD color;
8837     DWORD r0, g0, b0, r1, g1, b1;
8838     int fmt_index;
8839
8840     static const float quad[][5] = {
8841         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8842         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8843         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8844         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8845     };
8846
8847     /* Quad with R=0x10, G=0x20 */
8848     static const struct vertex quad1[] = {
8849         {-1.0f, -1.0f, 0.1f, 0x80102000},
8850         {-1.0f,  1.0f, 0.1f, 0x80102000},
8851         { 1.0f, -1.0f, 0.1f, 0x80102000},
8852         { 1.0f,  1.0f, 0.1f, 0x80102000},
8853     };
8854
8855     /* Quad with R=0x20, G=0x10 */
8856     static const struct vertex quad2[] = {
8857         {-1.0f, -1.0f, 0.1f, 0x80201000},
8858         {-1.0f,  1.0f, 0.1f, 0x80201000},
8859         { 1.0f, -1.0f, 0.1f, 0x80201000},
8860         { 1.0f,  1.0f, 0.1f, 0x80201000},
8861     };
8862
8863     IDirect3DDevice9_GetDirect3D(device, &d3d);
8864
8865     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8866     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8867     if(!backbuffer) {
8868         goto out;
8869     }
8870
8871     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8872     {
8873         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8874         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8875            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8876            continue;
8877         }
8878
8879         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8880         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8881
8882         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8883         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8884         if(!offscreenTexture) {
8885             continue;
8886         }
8887
8888         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8889         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8890         if(!offscreen) {
8891             continue;
8892         }
8893
8894         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8895         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8896
8897         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8898         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8899         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8900         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8901         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8902         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8903         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8904         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8905         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8906         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8907
8908         /* Below we will draw two quads with different colors and try to blend them together.
8909          * The result color is compared with the expected outcome.
8910          */
8911         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8912             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8913             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8914             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8915             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8916
8917             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8918             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8919
8920             /* Draw a quad using color 0x0010200 */
8921             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8922             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8923             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8924             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8925             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8926             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8927
8928             /* Draw a quad using color 0x0020100 */
8929             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8930             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8931             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8932             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8933             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8934             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8935
8936             /* We don't want to blend the result on the backbuffer */
8937             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8938             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8939
8940             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8941             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8942             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8943             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8944             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8945
8946             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8947             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8948
8949             /* This time with the texture */
8950             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8951             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8952
8953             IDirect3DDevice9_EndScene(device);
8954         }
8955         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8956
8957
8958         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8959             /* Compare the color of the center quad with our expectation */
8960             color = getPixelColor(device, 320, 240);
8961             r0 = (color & 0x00ff0000) >> 16;
8962             g0 = (color & 0x0000ff00) >>  8;
8963             b0 = (color & 0x000000ff) >>  0;
8964
8965             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8966             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8967             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8968
8969             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8970                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8971                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8972                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8973         } else {
8974             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8975              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8976              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8977             color = getPixelColor(device, 320, 240);
8978             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);
8979         }
8980
8981         IDirect3DDevice9_SetTexture(device, 0, NULL);
8982         if(offscreenTexture) {
8983             IDirect3DTexture9_Release(offscreenTexture);
8984         }
8985         if(offscreen) {
8986             IDirect3DSurface9_Release(offscreen);
8987         }
8988     }
8989
8990 out:
8991     /* restore things */
8992     if(backbuffer) {
8993         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8994         IDirect3DSurface9_Release(backbuffer);
8995     }
8996 }
8997
8998 static void tssargtemp_test(IDirect3DDevice9 *device)
8999 {
9000     HRESULT hr;
9001     DWORD color;
9002     static const struct vertex quad[] = {
9003         {-1.0,     -1.0,    0.1,    0x00ff0000},
9004         { 1.0,     -1.0,    0.1,    0x00ff0000},
9005         {-1.0,      1.0,    0.1,    0x00ff0000},
9006         { 1.0,      1.0,    0.1,    0x00ff0000}
9007     };
9008     D3DCAPS9 caps;
9009
9010     memset(&caps, 0, sizeof(caps));
9011     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9012     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9013     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9014         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9015         return;
9016     }
9017
9018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9020
9021     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9022     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9023     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9024     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9025
9026     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9027     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9028     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9029     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9030     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9031     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9032
9033     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9034     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9035     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9036     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9037     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9038     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9039
9040     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9041     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9042
9043     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9044     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9045     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9046     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9047
9048     hr = IDirect3DDevice9_BeginScene(device);
9049     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9050     if(SUCCEEDED(hr)) {
9051
9052         hr = IDirect3DDevice9_EndScene(device);
9053         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9054         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9055         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9056     }
9057     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9058     color = getPixelColor(device, 320, 240);
9059     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9060
9061     /* Set stage 1 back to default */
9062     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9063     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9064     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9065     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9066     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9067     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9068     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9069     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9070     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9071     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9072 }
9073
9074 struct testdata
9075 {
9076     DWORD idxVertex; /* number of instances in the first stream */
9077     DWORD idxColor; /* number of instances in the second stream */
9078     DWORD idxInstance; /* should be 1 ?? */
9079     DWORD color1; /* color 1 instance */
9080     DWORD color2; /* color 2 instance */
9081     DWORD color3; /* color 3 instance */
9082     DWORD color4; /* color 4 instance */
9083     WORD strVertex; /* specify which stream to use 0-2*/
9084     WORD strColor;
9085     WORD strInstance;
9086 };
9087
9088 static const struct testdata testcases[]=
9089 {
9090     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9091     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9092     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9093     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9094     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9095     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9096     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9097     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9098     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9099     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9100     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9101     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9102     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9103     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9104     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9105 /*
9106     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9107     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9108 */
9109 };
9110
9111 /* Drawing Indexed Geometry with instances*/
9112 static void stream_test(IDirect3DDevice9 *device)
9113 {
9114     IDirect3DVertexBuffer9 *vb = NULL;
9115     IDirect3DVertexBuffer9 *vb2 = NULL;
9116     IDirect3DVertexBuffer9 *vb3 = NULL;
9117     IDirect3DIndexBuffer9 *ib = NULL;
9118     IDirect3DVertexDeclaration9 *pDecl = NULL;
9119     IDirect3DVertexShader9 *shader = NULL;
9120     HRESULT hr;
9121     BYTE *data;
9122     DWORD color;
9123     DWORD ind;
9124     unsigned i;
9125
9126     const DWORD shader_code[] =
9127     {
9128         0xfffe0101,                                     /* vs_1_1 */
9129         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9130         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9131         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9132         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9133         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9134         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9135         0x0000ffff
9136     };
9137
9138     const float quad[][3] =
9139     {
9140         {-0.5f, -0.5f,  1.1f}, /*0 */
9141         {-0.5f,  0.5f,  1.1f}, /*1 */
9142         { 0.5f, -0.5f,  1.1f}, /*2 */
9143         { 0.5f,  0.5f,  1.1f}, /*3 */
9144     };
9145
9146     const float vertcolor[][4] =
9147     {
9148         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9149         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9150         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9151         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9152     };
9153
9154     /* 4 position for 4 instances */
9155     const float instancepos[][3] =
9156     {
9157         {-0.6f,-0.6f, 0.0f},
9158         { 0.6f,-0.6f, 0.0f},
9159         { 0.6f, 0.6f, 0.0f},
9160         {-0.6f, 0.6f, 0.0f},
9161     };
9162
9163     short indices[] = {0, 1, 2, 1, 2, 3};
9164
9165     D3DVERTEXELEMENT9 decl[] =
9166     {
9167         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9168         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9169         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9170         D3DDECL_END()
9171     };
9172
9173     /* set the default value because it isn't done in wine? */
9174     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9175     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9176
9177     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9178     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9179     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9180
9181     /* check wrong cases */
9182     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9183     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9184     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9185     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9186     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9187     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9188     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9189     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9190     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9191     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9192     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9193     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9194     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9195     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9196     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9197     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9198     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9199     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9200     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9201     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9202
9203     /* set the default value back */
9204     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9205     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9206
9207     /* create all VertexBuffers*/
9208     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9209     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9210     if(!vb) {
9211         skip("Failed to create a vertex buffer\n");
9212         return;
9213     }
9214     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9215     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9216     if(!vb2) {
9217         skip("Failed to create a vertex buffer\n");
9218         goto out;
9219     }
9220     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9221     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9222     if(!vb3) {
9223         skip("Failed to create a vertex buffer\n");
9224         goto out;
9225     }
9226
9227     /* create IndexBuffer*/
9228     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9229     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9230     if(!ib) {
9231         skip("Failed to create a index buffer\n");
9232         goto out;
9233     }
9234
9235     /* copy all Buffers (Vertex + Index)*/
9236     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9237     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9238     memcpy(data, quad, sizeof(quad));
9239     hr = IDirect3DVertexBuffer9_Unlock(vb);
9240     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9241     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9242     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9243     memcpy(data, vertcolor, sizeof(vertcolor));
9244     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9245     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9246     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9247     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9248     memcpy(data, instancepos, sizeof(instancepos));
9249     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9250     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9251     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9252     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9253     memcpy(data, indices, sizeof(indices));
9254     hr = IDirect3DIndexBuffer9_Unlock(ib);
9255     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9256
9257     /* create VertexShader */
9258     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9259     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9260     if(!shader) {
9261         skip("Failed to create a vetex shader\n");
9262         goto out;
9263     }
9264
9265     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9266     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9267
9268     hr = IDirect3DDevice9_SetIndices(device, ib);
9269     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9270
9271     /* run all tests */
9272     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9273     {
9274         struct testdata act = testcases[i];
9275         decl[0].Stream = act.strVertex;
9276         decl[1].Stream = act.strColor;
9277         decl[2].Stream = act.strInstance;
9278         /* create VertexDeclarations */
9279         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9280         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9281
9282         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9283         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9284
9285         hr = IDirect3DDevice9_BeginScene(device);
9286         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9287         if(SUCCEEDED(hr))
9288         {
9289             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9290             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9291
9292             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9293             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9294             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9295             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9296
9297             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9298             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9299             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9300             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9301
9302             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9303             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9304             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9305             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9306
9307             /* don't know if this is right (1*3 and 4*1)*/
9308             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9309             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9310             hr = IDirect3DDevice9_EndScene(device);
9311             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9312
9313             /* set all StreamSource && StreamSourceFreq back to default */
9314             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9315             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9316             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9317             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9318             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9319             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9320             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9321             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9322             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9323             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9324             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9325             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9326         }
9327
9328         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9329         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9330
9331         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9332         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9333
9334         color = getPixelColor(device, 160, 360);
9335         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9336         color = getPixelColor(device, 480, 360);
9337         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9338         color = getPixelColor(device, 480, 120);
9339         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9340         color = getPixelColor(device, 160, 120);
9341         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9342     }
9343
9344     hr = IDirect3DDevice9_SetIndices(device, NULL);
9345     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9346
9347 out:
9348     if(vb) IDirect3DVertexBuffer9_Release(vb);
9349     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9350     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9351     if(ib)IDirect3DIndexBuffer9_Release(ib);
9352     if(shader)IDirect3DVertexShader9_Release(shader);
9353 }
9354
9355 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9356     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9357     IDirect3DTexture9 *dsttex = NULL;
9358     HRESULT hr;
9359     DWORD color;
9360     D3DRECT r1 = {0,  0,  50,  50 };
9361     D3DRECT r2 = {50, 0,  100, 50 };
9362     D3DRECT r3 = {50, 50, 100, 100};
9363     D3DRECT r4 = {0,  50,  50, 100};
9364     const float quad[] = {
9365         -1.0,   -1.0,   0.1,    0.0,    0.0,
9366          1.0,   -1.0,   0.1,    1.0,    0.0,
9367         -1.0,    1.0,   0.1,    0.0,    1.0,
9368          1.0,    1.0,   0.1,    1.0,    1.0,
9369     };
9370
9371     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9372     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9373
9374     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9375     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9376     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9377     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9378
9379     if(!src || !dsttex) {
9380         skip("One or more test resources could not be created\n");
9381         goto cleanup;
9382     }
9383
9384     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9385     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9386
9387     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9388     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9389
9390     /* Clear the StretchRect destination for debugging */
9391     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9392     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9393     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9394     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9395
9396     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9397     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9398
9399     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9400     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9401     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9402     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9403     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9404     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9405     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9406     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9407
9408     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9409      * the target -> texture GL blit path
9410      */
9411     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9412     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9413     IDirect3DSurface9_Release(dst);
9414
9415     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9416     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9417
9418     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9419     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9420     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9421     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9422     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9423     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9424     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9425     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9426
9427     hr = IDirect3DDevice9_BeginScene(device);
9428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9429     if(SUCCEEDED(hr)) {
9430         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9431         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9432         hr = IDirect3DDevice9_EndScene(device);
9433         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9434     }
9435
9436     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9437     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9438     color = getPixelColor(device, 160, 360);
9439     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9440     color = getPixelColor(device, 480, 360);
9441     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9442     color = getPixelColor(device, 480, 120);
9443     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9444     color = getPixelColor(device, 160, 120);
9445     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9446
9447     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9448     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9449     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9450     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9451
9452 cleanup:
9453     if(src) IDirect3DSurface9_Release(src);
9454     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9455     if(dsttex) IDirect3DTexture9_Release(dsttex);
9456 }
9457
9458 static void texop_test(IDirect3DDevice9 *device)
9459 {
9460     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9461     IDirect3DTexture9 *texture = NULL;
9462     D3DLOCKED_RECT locked_rect;
9463     D3DCOLOR color;
9464     D3DCAPS9 caps;
9465     HRESULT hr;
9466     unsigned i;
9467
9468     static const struct {
9469         float x, y, z;
9470         float s, t;
9471         D3DCOLOR diffuse;
9472     } quad[] = {
9473         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9474         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9475         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9476         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9477     };
9478
9479     static const D3DVERTEXELEMENT9 decl_elements[] = {
9480         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9481         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9482         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9483         D3DDECL_END()
9484     };
9485
9486     static const struct {
9487         D3DTEXTUREOP op;
9488         const char *name;
9489         DWORD caps_flag;
9490         D3DCOLOR result;
9491     } test_data[] = {
9492         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9493         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9494         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9495         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9496         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9497         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9498         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9499         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9500         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9501         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9502         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9503         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9504         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9505         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9506         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9507         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9508         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9509         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9510         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9511         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9512         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9513         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9514         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9515     };
9516
9517     memset(&caps, 0, sizeof(caps));
9518     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9519     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9520
9521     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9522     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9523     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9524     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9525
9526     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9527     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9528     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9529     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9530     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9531     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9532     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9533     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9534     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9535
9536     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9537     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9538     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9539     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9540     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9541     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9542
9543     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9544     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9545
9546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9547     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9549     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9551     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9552
9553     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9554     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9555
9556     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9557     {
9558         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9559         {
9560             skip("tex operation %s not supported\n", test_data[i].name);
9561             continue;
9562         }
9563
9564         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9565         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9566
9567         hr = IDirect3DDevice9_BeginScene(device);
9568         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9569
9570         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9571         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9572
9573         hr = IDirect3DDevice9_EndScene(device);
9574         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9575
9576         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9577         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9578
9579         color = getPixelColor(device, 320, 240);
9580         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9581                 test_data[i].name, color, test_data[i].result);
9582     }
9583
9584     if (texture) IDirect3DTexture9_Release(texture);
9585     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9586 }
9587
9588 static void yuv_color_test(IDirect3DDevice9 *device) {
9589     HRESULT hr;
9590     IDirect3DSurface9 *surface = NULL, *target = NULL;
9591     unsigned int fmt, i;
9592     D3DFORMAT format;
9593     const char *fmt_string;
9594     D3DLOCKED_RECT lr;
9595     IDirect3D9 *d3d;
9596     HRESULT color;
9597     DWORD ref_color_left, ref_color_right;
9598
9599     struct {
9600         DWORD in;           /* The input color */
9601         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9602         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9603         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9604         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9605     } test_data[] = {
9606     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9607      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9608      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9609      * that
9610      */
9611       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9612       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9613       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9614       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9615       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9616       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9617       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9618       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9619       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9620       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9621       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9622       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9623       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9624       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9625
9626       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9627       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9628       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9629       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9630     };
9631
9632     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9633     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9634     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9635     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9636
9637     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9638     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9639
9640     for(fmt = 0; fmt < 2; fmt++) {
9641         if(fmt == 0) {
9642             format = D3DFMT_UYVY;
9643             fmt_string = "D3DFMT_UYVY";
9644         } else {
9645             format = D3DFMT_YUY2;
9646             fmt_string = "D3DFMT_YUY2";
9647         }
9648
9649         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9650                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9651                        */
9652         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9653                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9654             skip("%s is not supported\n", fmt_string);
9655             continue;
9656         }
9657
9658         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9659         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9660         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9661
9662         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9663             if(fmt == 0) {
9664                 ref_color_left = test_data[i].uyvy_left;
9665                 ref_color_right = test_data[i].uyvy_right;
9666             } else {
9667                 ref_color_left = test_data[i].yuy2_left;
9668                 ref_color_right = test_data[i].yuy2_right;
9669             }
9670
9671             memset(&lr, 0, sizeof(lr));
9672             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9673             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9674             *((DWORD *) lr.pBits) = test_data[i].in;
9675             hr = IDirect3DSurface9_UnlockRect(surface);
9676             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9677
9678             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9679             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9680             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9681             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9682             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9683             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9684
9685             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9686              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9687              * want to add tests for the filtered pixels as well.
9688              *
9689              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9690              * differently, so we need a max diff of 16
9691              */
9692             color = getPixelColor(device, 40, 240);
9693             ok(color_match(color, ref_color_left, 16),
9694                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9695                test_data[i].in, color, ref_color_left, fmt_string);
9696             color = getPixelColor(device, 600, 240);
9697             ok(color_match(color, ref_color_right, 16),
9698                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9699                test_data[i].in, color, ref_color_right, fmt_string);
9700         }
9701         IDirect3DSurface9_Release(surface);
9702     }
9703     IDirect3DSurface9_Release(target);
9704     IDirect3D9_Release(d3d);
9705 }
9706
9707 static void texop_range_test(IDirect3DDevice9 *device)
9708 {
9709     static const struct {
9710         float x, y, z;
9711         D3DCOLOR diffuse;
9712     } quad[] = {
9713         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9714         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9715         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9716         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9717     };
9718     HRESULT hr;
9719     IDirect3DTexture9 *texture;
9720     D3DLOCKED_RECT locked_rect;
9721     D3DCAPS9 caps;
9722     DWORD color;
9723
9724     /* We need ADD and SUBTRACT operations */
9725     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9726     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9727     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9728         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9729     }
9730     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9731         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9732     }
9733
9734     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9735     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9736     /* Stage 1: result = diffuse(=1.0) + diffuse
9737      * stage 2: result = result - tfactor(= 0.5)
9738      */
9739     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9740     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9741     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9742     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9743     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9744     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9745     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9746     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9747     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9748     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9749     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9750     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9751     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9752     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9753
9754     hr = IDirect3DDevice9_BeginScene(device);
9755     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9756     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9757     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9758     hr = IDirect3DDevice9_EndScene(device);
9759     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9760     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9761     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9762
9763     color = getPixelColor(device, 320, 240);
9764     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9765        color);
9766
9767     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9768     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9769     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9770     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9771     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9772     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9773     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9774     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9775     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9776
9777     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9778      * stage 2: result = result + diffuse(1.0)
9779      */
9780     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9781     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9782     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9783     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9784     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9785     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9786     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9787     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9788     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9789     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9790     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9791     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9792     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9793     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9794
9795     hr = IDirect3DDevice9_BeginScene(device);
9796     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9797     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9798     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9799     hr = IDirect3DDevice9_EndScene(device);
9800     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9801     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9802     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9803
9804     color = getPixelColor(device, 320, 240);
9805     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9806        color);
9807
9808     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9809     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9810     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9811     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9812     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9813     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9814     IDirect3DTexture9_Release(texture);
9815 }
9816
9817 static void alphareplicate_test(IDirect3DDevice9 *device) {
9818     struct vertex quad[] = {
9819         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9820         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9821         { -1.0,     1.0,    0.1,    0x80ff00ff },
9822         {  1.0,     1.0,    0.1,    0x80ff00ff },
9823     };
9824     HRESULT hr;
9825     DWORD color;
9826
9827     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9828     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9829
9830     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9831     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9832
9833     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9834     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9835     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9836     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9837
9838     hr = IDirect3DDevice9_BeginScene(device);
9839     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9840     if(SUCCEEDED(hr)) {
9841         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9842         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9843         hr = IDirect3DDevice9_EndScene(device);
9844         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9845     }
9846
9847     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9848     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9849
9850     color = getPixelColor(device, 320, 240);
9851     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9852        color);
9853
9854     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9855     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9856
9857 }
9858
9859 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9860     HRESULT hr;
9861     D3DCAPS9 caps;
9862     DWORD color;
9863     struct vertex quad[] = {
9864         { -1.0,    -1.0,    0.1,    0x408080c0 },
9865         {  1.0,    -1.0,    0.1,    0x408080c0 },
9866         { -1.0,     1.0,    0.1,    0x408080c0 },
9867         {  1.0,     1.0,    0.1,    0x408080c0 },
9868     };
9869
9870     memset(&caps, 0, sizeof(caps));
9871     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9872     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9873     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9874         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9875         return;
9876     }
9877
9878     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9879     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9880
9881     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9882     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9883
9884     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9885      * mov r0.a, diffuse.a
9886      * mov r0, r0.a
9887      *
9888      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9889      * 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
9890      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9891      */
9892     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9893     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9894     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9895     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9896     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9897     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9898     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9899     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9900     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9901     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9902     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9903     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9905     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9906     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9907     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9908     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9909     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9910
9911     hr = IDirect3DDevice9_BeginScene(device);
9912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9913     if(SUCCEEDED(hr)) {
9914         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9915         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9916         hr = IDirect3DDevice9_EndScene(device);
9917         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9918     }
9919
9920     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9921     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9922
9923     color = getPixelColor(device, 320, 240);
9924     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9925        color);
9926
9927     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9928     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9929     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9930     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9931     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9932     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9933 }
9934
9935 static void zwriteenable_test(IDirect3DDevice9 *device) {
9936     HRESULT hr;
9937     DWORD color;
9938     struct vertex quad1[] = {
9939         { -1.0,  -1.0,  0.1,    0x00ff0000},
9940         { -1.0,   1.0,  0.1,    0x00ff0000},
9941         {  1.0,  -1.0,  0.1,    0x00ff0000},
9942         {  1.0,   1.0,  0.1,    0x00ff0000},
9943     };
9944     struct vertex quad2[] = {
9945         { -1.0,  -1.0,  0.9,    0x0000ff00},
9946         { -1.0,   1.0,  0.9,    0x0000ff00},
9947         {  1.0,  -1.0,  0.9,    0x0000ff00},
9948         {  1.0,   1.0,  0.9,    0x0000ff00},
9949     };
9950
9951     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9952     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9953
9954     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9955     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9956     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9957     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9958     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9959     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9960     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9961     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9962
9963     hr = IDirect3DDevice9_BeginScene(device);
9964     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9965     if(SUCCEEDED(hr)) {
9966         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9967          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9968          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9969          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9970          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9971          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9972          */
9973         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9974         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9975         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9976         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9977         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9978         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9979
9980         hr = IDirect3DDevice9_EndScene(device);
9981         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9982     }
9983
9984     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9985     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9986     color = getPixelColor(device, 320, 240);
9987     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9988        color);
9989
9990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9991     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9992 }
9993
9994 static void alphatest_test(IDirect3DDevice9 *device) {
9995 #define ALPHATEST_PASSED 0x0000ff00
9996 #define ALPHATEST_FAILED 0x00ff0000
9997     struct {
9998         D3DCMPFUNC  func;
9999         DWORD       color_less;
10000         DWORD       color_equal;
10001         DWORD       color_greater;
10002     } testdata[] = {
10003         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10004         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10005         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10006         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10007         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10008         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10009         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10010         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10011     };
10012     unsigned int i, j;
10013     HRESULT hr;
10014     DWORD color;
10015     struct vertex quad[] = {
10016         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10017         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10018         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10019         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10020     };
10021     D3DCAPS9 caps;
10022
10023     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10024     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10025     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10026     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10027
10028     for(j = 0; j < 2; j++) {
10029         if(j == 1) {
10030             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10031              * the alpha test either for performance reasons(floating point RTs) or to work
10032              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10033              * codepath for ffp and shader in this case, and the test should cover both
10034              */
10035             IDirect3DPixelShader9 *ps;
10036             DWORD shader_code[] = {
10037                 0xffff0101,                                 /* ps_1_1           */
10038                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10039                 0x0000ffff                                  /* end              */
10040             };
10041             memset(&caps, 0, sizeof(caps));
10042             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10043             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10044             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10045                 break;
10046             }
10047
10048             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10049             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10050             IDirect3DDevice9_SetPixelShader(device, ps);
10051             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10052             IDirect3DPixelShader9_Release(ps);
10053         }
10054
10055         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10056             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10057             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10058
10059             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10060             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10061             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10062             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10063             hr = IDirect3DDevice9_BeginScene(device);
10064             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10065             if(SUCCEEDED(hr)) {
10066                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10067                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10068                 hr = IDirect3DDevice9_EndScene(device);
10069                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10070             }
10071             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10072             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10073             color = getPixelColor(device, 320, 240);
10074             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10075             color, testdata[i].color_less, testdata[i].func);
10076
10077             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10078             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10079             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10080             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10081             hr = IDirect3DDevice9_BeginScene(device);
10082             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10083             if(SUCCEEDED(hr)) {
10084                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10085                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10086                 hr = IDirect3DDevice9_EndScene(device);
10087                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10088             }
10089             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10090             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10091             color = getPixelColor(device, 320, 240);
10092             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10093             color, testdata[i].color_equal, testdata[i].func);
10094
10095             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10096             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10097             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10098             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10099             hr = IDirect3DDevice9_BeginScene(device);
10100             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10101             if(SUCCEEDED(hr)) {
10102                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10103                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10104                 hr = IDirect3DDevice9_EndScene(device);
10105                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10106             }
10107             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10108             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10109             color = getPixelColor(device, 320, 240);
10110             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10111             color, testdata[i].color_greater, testdata[i].func);
10112         }
10113     }
10114
10115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10117     IDirect3DDevice9_SetPixelShader(device, NULL);
10118     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10119 }
10120
10121 static void sincos_test(IDirect3DDevice9 *device) {
10122     const DWORD sin_shader_code[] = {
10123         0xfffe0200,                                                                 /* vs_2_0                       */
10124         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10125         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10126         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10127         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10128         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10129         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10130         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10131         0x0000ffff                                                                  /* end                          */
10132     };
10133     const DWORD cos_shader_code[] = {
10134         0xfffe0200,                                                                 /* vs_2_0                       */
10135         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10136         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10137         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10138         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10139         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10140         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10141         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10142         0x0000ffff                                                                  /* end                          */
10143     };
10144     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10145     HRESULT hr;
10146     struct {
10147         float x, y, z;
10148     } data[1280];
10149     unsigned int i;
10150     float sincosc1[4] = {D3DSINCOSCONST1};
10151     float sincosc2[4] = {D3DSINCOSCONST2};
10152
10153     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10154     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10155
10156     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10157     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10158     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10159     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10160     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10161     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10162     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10163     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10164     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10165     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10166
10167     /* Generate a point from -1 to 1 every 0.5 pixels */
10168     for(i = 0; i < 1280; i++) {
10169         data[i].x = (-640.0 + i) / 640.0;
10170         data[i].y = 0.0;
10171         data[i].z = 0.1;
10172     }
10173
10174     hr = IDirect3DDevice9_BeginScene(device);
10175     if(SUCCEEDED(hr)) {
10176         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10177         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10178         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10179         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10180
10181         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10182         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10183         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10184         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10185
10186         hr = IDirect3DDevice9_EndScene(device);
10187         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10188     }
10189     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10190     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10191
10192     IDirect3DDevice9_SetVertexShader(device, NULL);
10193     IDirect3DVertexShader9_Release(sin_shader);
10194     IDirect3DVertexShader9_Release(cos_shader);
10195 }
10196
10197 static void loop_index_test(IDirect3DDevice9 *device) {
10198     const DWORD shader_code[] = {
10199         0xfffe0200,                                                 /* vs_2_0                   */
10200         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10201         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10202         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10203         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10204         0x0000001d,                                                 /* endloop                  */
10205         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10206         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10207         0x0000ffff                                                  /* END                      */
10208     };
10209     IDirect3DVertexShader9 *shader;
10210     HRESULT hr;
10211     DWORD color;
10212     const float quad[] = {
10213         -1.0,   -1.0,   0.1,
10214          1.0,   -1.0,   0.1,
10215         -1.0,    1.0,   0.1,
10216          1.0,    1.0,   0.1
10217     };
10218     const float zero[4] = {0, 0, 0, 0};
10219     const float one[4] = {1, 1, 1, 1};
10220     int i0[4] = {2, 10, -3, 0};
10221     float values[4];
10222
10223     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10225     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10226     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10227     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10228     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10229     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10230     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10231
10232     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10233     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10234     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10235     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10236     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10237     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10238     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10239     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10240     values[0] = 1.0;
10241     values[1] = 1.0;
10242     values[2] = 0.0;
10243     values[3] = 0.0;
10244     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10245     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10246     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10247     values[0] = -1.0;
10248     values[1] = 0.0;
10249     values[2] = 0.0;
10250     values[3] = 0.0;
10251     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10252     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10253     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10254     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10255     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10256
10257     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10258
10259     hr = IDirect3DDevice9_BeginScene(device);
10260     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10261     if(SUCCEEDED(hr))
10262     {
10263         trace("going to draw index\n");
10264         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10265         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10266         hr = IDirect3DDevice9_EndScene(device);
10267         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10268     }
10269     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10270     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10271
10272     color = getPixelColor(device, 320, 240);
10273     ok(color_match(color, 0x0000ff00, 1),
10274        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10275
10276     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10277     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10278     IDirect3DVertexShader9_Release(shader);
10279 }
10280
10281 static void sgn_test(IDirect3DDevice9 *device) {
10282     const DWORD shader_code[] = {
10283         0xfffe0200,                                                             /* vs_2_0                       */
10284         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10285         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10286         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10287         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10288         0x02000022, 0x800f0000, 0xa0e40000,                                     /* sgn r0, c0                   */
10289         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10290         0x0000ffff                                                              /* end                          */
10291     };
10292     IDirect3DVertexShader9 *shader;
10293     HRESULT hr;
10294     DWORD color;
10295     const float quad[] = {
10296         -1.0,   -1.0,   0.1,
10297          1.0,   -1.0,   0.1,
10298         -1.0,    1.0,   0.1,
10299          1.0,    1.0,   0.1
10300     };
10301
10302     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10304     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10305     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10306     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10307     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10308     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10309     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10310
10311     hr = IDirect3DDevice9_BeginScene(device);
10312     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10313     if(SUCCEEDED(hr))
10314     {
10315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10316         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10317         hr = IDirect3DDevice9_EndScene(device);
10318         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10319     }
10320     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10321     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10322
10323     color = getPixelColor(device, 320, 240);
10324     ok(color_match(color, 0x008000ff, 1),
10325        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10326
10327     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10328     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10329     IDirect3DVertexShader9_Release(shader);
10330 }
10331
10332 START_TEST(visual)
10333 {
10334     IDirect3DDevice9 *device_ptr;
10335     D3DCAPS9 caps;
10336     HRESULT hr;
10337     DWORD color;
10338
10339     d3d9_handle = LoadLibraryA("d3d9.dll");
10340     if (!d3d9_handle)
10341     {
10342         skip("Could not load d3d9.dll\n");
10343         return;
10344     }
10345
10346     device_ptr = init_d3d9();
10347     if (!device_ptr)
10348     {
10349         skip("Creating the device failed\n");
10350         return;
10351     }
10352
10353     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10354
10355     /* Check for the reliability of the returned data */
10356     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10357     if(FAILED(hr))
10358     {
10359         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10360         goto cleanup;
10361     }
10362     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10363
10364     color = getPixelColor(device_ptr, 1, 1);
10365     if(color !=0x00ff0000)
10366     {
10367         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10368         goto cleanup;
10369     }
10370
10371     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10372     if(FAILED(hr))
10373     {
10374         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10375         goto cleanup;
10376     }
10377     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10378
10379     color = getPixelColor(device_ptr, 639, 479);
10380     if(color != 0x0000ddee)
10381     {
10382         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10383         goto cleanup;
10384     }
10385
10386     /* Now execute the real tests */
10387     stretchrect_test(device_ptr);
10388     lighting_test(device_ptr);
10389     clear_test(device_ptr);
10390     fog_test(device_ptr);
10391     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10392     {
10393         test_cube_wrap(device_ptr);
10394     } else {
10395         skip("No cube texture support\n");
10396     }
10397     z_range_test(device_ptr);
10398     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10399     {
10400         maxmip_test(device_ptr);
10401     }
10402     else
10403     {
10404         skip("No mipmap support\n");
10405     }
10406     offscreen_test(device_ptr);
10407     alpha_test(device_ptr);
10408     shademode_test(device_ptr);
10409     srgbtexture_test(device_ptr);
10410     release_buffer_test(device_ptr);
10411     float_texture_test(device_ptr);
10412     g16r16_texture_test(device_ptr);
10413     pixelshader_blending_test(device_ptr);
10414     texture_transform_flags_test(device_ptr);
10415     autogen_mipmap_test(device_ptr);
10416     fixed_function_decl_test(device_ptr);
10417     conditional_np2_repeat_test(device_ptr);
10418     fixed_function_bumpmap_test(device_ptr);
10419     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10420         stencil_cull_test(device_ptr);
10421     } else {
10422         skip("No two sided stencil support\n");
10423     }
10424     pointsize_test(device_ptr);
10425     tssargtemp_test(device_ptr);
10426     np2_stretch_rect_test(device_ptr);
10427     yuv_color_test(device_ptr);
10428     zwriteenable_test(device_ptr);
10429     alphatest_test(device_ptr);
10430
10431     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10432     {
10433         test_constant_clamp_vs(device_ptr);
10434         test_compare_instructions(device_ptr);
10435     }
10436     else skip("No vs_1_1 support\n");
10437
10438     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10439     {
10440         test_mova(device_ptr);
10441         loop_index_test(device_ptr);
10442         sincos_test(device_ptr);
10443         sgn_test(device_ptr);
10444         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10445             test_vshader_input(device_ptr);
10446             test_vshader_float16(device_ptr);
10447             stream_test(device_ptr);
10448         } else {
10449             skip("No vs_3_0 support\n");
10450         }
10451     }
10452     else skip("No vs_2_0 support\n");
10453
10454     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10455     {
10456         fog_with_shader_test(device_ptr);
10457         fog_srgbwrite_test(device_ptr);
10458     }
10459     else skip("No vs_1_1 and ps_1_1 support\n");
10460
10461     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10462     {
10463         texbem_test(device_ptr);
10464         texdepth_test(device_ptr);
10465         texkill_test(device_ptr);
10466         x8l8v8u8_test(device_ptr);
10467         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10468             constant_clamp_ps_test(device_ptr);
10469             cnd_test(device_ptr);
10470             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10471                 dp2add_ps_test(device_ptr);
10472                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10473                     nested_loop_test(device_ptr);
10474                     fixed_function_varying_test(device_ptr);
10475                     vFace_register_test(device_ptr);
10476                     vpos_register_test(device_ptr);
10477                     multiple_rendertargets_test(device_ptr);
10478                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10479                         vshader_version_varying_test(device_ptr);
10480                         pshader_version_varying_test(device_ptr);
10481                     } else {
10482                         skip("No vs_3_0 support\n");
10483                     }
10484                 } else {
10485                     skip("No ps_3_0 support\n");
10486                 }
10487             } else {
10488                 skip("No ps_2_0 support\n");
10489             }
10490         }
10491     }
10492     else skip("No ps_1_1 support\n");
10493
10494     texop_test(device_ptr);
10495     texop_range_test(device_ptr);
10496     alphareplicate_test(device_ptr);
10497     dp3_alpha_test(device_ptr);
10498
10499 cleanup:
10500     if(device_ptr) {
10501         D3DPRESENT_PARAMETERS present_parameters;
10502         IDirect3DSwapChain9 *swapchain;
10503         ULONG ref;
10504
10505         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10506         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10507         DestroyWindow(present_parameters.hDeviceWindow);
10508         IDirect3DSwapChain9_Release(swapchain);
10509         ref = IDirect3DDevice9_Release(device_ptr);
10510         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10511     }
10512 }