jscript: Make String_slice generic.
[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;
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     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3062        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3063
3064 out:
3065     if(texture) IDirect3DTexture9_Release(texture);
3066     IDirect3D9_Release(d3d);
3067 }
3068
3069 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3070 {
3071     HRESULT hr;
3072     IDirect3D9 *d3d;
3073     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3074     D3DCAPS9 caps;
3075     IDirect3DTexture9 *texture = NULL;
3076     IDirect3DVolumeTexture9 *volume = NULL;
3077     unsigned int x, y, z;
3078     D3DLOCKED_RECT lr;
3079     D3DLOCKED_BOX lb;
3080     DWORD color;
3081     UINT w, h;
3082     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3083     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3084                            0.0, 1.0, 0.0, 0.0,
3085                            0.0, 0.0, 1.0, 0.0,
3086                            0.0, 0.0, 0.0, 1.0};
3087     static const D3DVERTEXELEMENT9 decl_elements[] = {
3088         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3089         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3090         D3DDECL_END()
3091     };
3092     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3093         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3094         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3095         D3DDECL_END()
3096     };
3097     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3098         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3099         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3100         D3DDECL_END()
3101     };
3102     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3103                                                  0x00, 0xff, 0x00, 0x00,
3104                                                  0x00, 0x00, 0x00, 0x00,
3105                                                  0x00, 0x00, 0x00, 0x00};
3106
3107     memset(&lr, 0, sizeof(lr));
3108     memset(&lb, 0, sizeof(lb));
3109     IDirect3DDevice9_GetDirect3D(device, &d3d);
3110     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3111                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3112         fmt = D3DFMT_A16B16G16R16;
3113     }
3114     IDirect3D9_Release(d3d);
3115
3116     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3117     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3118     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3119     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3120     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3121     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3122     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3123     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3124     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3125     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3126     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3127     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3128     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3129     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3130     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3131     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3132     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3133     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3134     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3135     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3137     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3138     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3139     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3140
3141     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3142     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3143     w = min(1024, caps.MaxTextureWidth);
3144     h = min(1024, caps.MaxTextureHeight);
3145     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3146                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3147     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3148     if(!texture) {
3149         skip("Failed to create the test texture\n");
3150         return;
3151     }
3152
3153     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3154      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3155      * 1.0 in red and green for the x and y coords
3156      */
3157     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3158     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3159     for(y = 0; y < h; y++) {
3160         for(x = 0; x < w; x++) {
3161             double r_f = (double) y / (double) h;
3162             double g_f = (double) x / (double) w;
3163             if(fmt == D3DFMT_A16B16G16R16) {
3164                 unsigned short r, g;
3165                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3166                 r = (unsigned short) (r_f * 65536.0);
3167                 g = (unsigned short) (g_f * 65536.0);
3168                 dst[0] = r;
3169                 dst[1] = g;
3170                 dst[2] = 0;
3171                 dst[3] = 65535;
3172             } else {
3173                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3174                 unsigned char r = (unsigned char) (r_f * 255.0);
3175                 unsigned char g = (unsigned char) (g_f * 255.0);
3176                 dst[0] = 0;
3177                 dst[1] = g;
3178                 dst[2] = r;
3179                 dst[3] = 255;
3180             }
3181         }
3182     }
3183     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3184     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3185     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3186     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3187
3188     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3190     hr = IDirect3DDevice9_BeginScene(device);
3191     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3192     if(SUCCEEDED(hr))
3193     {
3194         float quad1[] = {
3195             -1.0,      -1.0,       0.1,     1.0,    1.0,
3196             -1.0,       0.0,       0.1,     1.0,    1.0,
3197              0.0,      -1.0,       0.1,     1.0,    1.0,
3198              0.0,       0.0,       0.1,     1.0,    1.0,
3199         };
3200         float quad2[] = {
3201             -1.0,       0.0,       0.1,     1.0,    1.0,
3202             -1.0,       1.0,       0.1,     1.0,    1.0,
3203              0.0,       0.0,       0.1,     1.0,    1.0,
3204              0.0,       1.0,       0.1,     1.0,    1.0,
3205         };
3206         float quad3[] = {
3207              0.0,       0.0,       0.1,     0.5,    0.5,
3208              0.0,       1.0,       0.1,     0.5,    0.5,
3209              1.0,       0.0,       0.1,     0.5,    0.5,
3210              1.0,       1.0,       0.1,     0.5,    0.5,
3211         };
3212         float quad4[] = {
3213              320,       480,       0.1,     1.0,    0.0,    1.0,
3214              320,       240,       0.1,     1.0,    0.0,    1.0,
3215              640,       480,       0.1,     1.0,    0.0,    1.0,
3216              640,       240,       0.1,     1.0,    0.0,    1.0,
3217         };
3218         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3219                           0.0, 0.0, 0.0, 0.0,
3220                           0.0, 0.0, 0.0, 0.0,
3221                           0.0, 0.0, 0.0, 0.0};
3222
3223         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3224         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3225         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3226         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3227         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3228
3229         /* What happens with transforms enabled? */
3230         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3231         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3232         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3233         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3234
3235         /* What happens if 4 coords are used, but only 2 given ?*/
3236         mat[8] = 1.0;
3237         mat[13] = 1.0;
3238         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3239         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3240         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3241         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3242         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3243         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3244
3245         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3246          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3247          * due to the coords in the vertices. (turns out red, indeed)
3248          */
3249         memset(mat, 0, sizeof(mat));
3250         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3251         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3252         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3253         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3254         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3255         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3256         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3257         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3258
3259         hr = IDirect3DDevice9_EndScene(device);
3260         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3261     }
3262     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3263     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3264     color = getPixelColor(device, 160, 360);
3265     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3266     color = getPixelColor(device, 160, 120);
3267     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3268     color = getPixelColor(device, 480, 120);
3269     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3270     color = getPixelColor(device, 480, 360);
3271     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3272
3273     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3274     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3275
3276     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3277     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3278     hr = IDirect3DDevice9_BeginScene(device);
3279     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3280     if(SUCCEEDED(hr))
3281     {
3282         float quad1[] = {
3283             -1.0,      -1.0,       0.1,     0.8,    0.2,
3284             -1.0,       0.0,       0.1,     0.8,    0.2,
3285              0.0,      -1.0,       0.1,     0.8,    0.2,
3286              0.0,       0.0,       0.1,     0.8,    0.2,
3287         };
3288         float quad2[] = {
3289             -1.0,       0.0,       0.1,     0.5,    1.0,
3290             -1.0,       1.0,       0.1,     0.5,    1.0,
3291              0.0,       0.0,       0.1,     0.5,    1.0,
3292              0.0,       1.0,       0.1,     0.5,    1.0,
3293         };
3294         float quad3[] = {
3295              0.0,       0.0,       0.1,     0.5,    1.0,
3296              0.0,       1.0,       0.1,     0.5,    1.0,
3297              1.0,       0.0,       0.1,     0.5,    1.0,
3298              1.0,       1.0,       0.1,     0.5,    1.0,
3299         };
3300         float quad4[] = {
3301              0.0,      -1.0,       0.1,     0.8,    0.2,
3302              0.0,       0.0,       0.1,     0.8,    0.2,
3303              1.0,      -1.0,       0.1,     0.8,    0.2,
3304              1.0,       0.0,       0.1,     0.8,    0.2,
3305         };
3306         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3307                           0.0, 0.0, 0.0, 0.0,
3308                           0.0, 1.0, 0.0, 0.0,
3309                           0.0, 0.0, 0.0, 0.0};
3310
3311         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3312          */
3313         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3314         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3315         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3316         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3317
3318         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3319         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3320
3321         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3322          * it behaves like COUNT2 because normal textures require 2 coords
3323          */
3324         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3325         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         /* Just to be sure, the same as quad2 above */
3330         memset(mat, 0, sizeof(mat));
3331         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3332         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3333         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3334         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3335         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3336         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3337
3338         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3339          * used? And what happens to the first?
3340          */
3341         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3342         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3343         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3344         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3345
3346         hr = IDirect3DDevice9_EndScene(device);
3347         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3348     }
3349     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3350     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3351     color = getPixelColor(device, 160, 360);
3352     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3353     color = getPixelColor(device, 160, 120);
3354     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3355     color = getPixelColor(device, 480, 120);
3356     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3357        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3358     color = getPixelColor(device, 480, 360);
3359     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3360        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3361
3362     IDirect3DTexture9_Release(texture);
3363
3364     /* Test projected textures, without any fancy matrices */
3365     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3366     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3367     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3368     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3369     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3370     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3371     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3372     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3373
3374     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3375     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3376     for(x = 0; x < 4; x++) {
3377         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3378     }
3379     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3380     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3381     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_BeginScene(device);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3386     if(SUCCEEDED(hr))
3387     {
3388         const float proj_quads[] = {
3389            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3390             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3391            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3392             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3393            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3394             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3395            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3396             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3397         };
3398
3399         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3400         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3401         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3402         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3403
3404         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3405         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3406         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3407         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3408
3409         hr = IDirect3DDevice9_EndScene(device);
3410         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3411     }
3412
3413     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3414     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3415     IDirect3DTexture9_Release(texture);
3416
3417     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3418     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3419     color = getPixelColor(device, 158, 118);
3420     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3421     color = getPixelColor(device, 162, 118);
3422     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3423     color = getPixelColor(device, 158, 122);
3424     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3425     color = getPixelColor(device, 162, 122);
3426     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3427
3428     color = getPixelColor(device, 158, 178);
3429     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3430     color = getPixelColor(device, 162, 178);
3431     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3432     color = getPixelColor(device, 158, 182);
3433     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3434     color = getPixelColor(device, 162, 182);
3435     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3436
3437     color = getPixelColor(device, 318, 118);
3438     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3439     color = getPixelColor(device, 322, 118);
3440     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3441     color = getPixelColor(device, 318, 122);
3442     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3443     color = getPixelColor(device, 322, 122);
3444     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3445
3446     color = getPixelColor(device, 318, 178);
3447     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3448     color = getPixelColor(device, 322, 178);
3449     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3450     color = getPixelColor(device, 318, 182);
3451     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3452     color = getPixelColor(device, 322, 182);
3453     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3454
3455     color = getPixelColor(device, 238, 298);
3456     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3457     color = getPixelColor(device, 242, 298);
3458     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3459     color = getPixelColor(device, 238, 302);
3460     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3461     color = getPixelColor(device, 242, 302);
3462     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3463
3464     color = getPixelColor(device, 238, 388);
3465     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3466     color = getPixelColor(device, 242, 388);
3467     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3468     color = getPixelColor(device, 238, 392);
3469     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3470     color = getPixelColor(device, 242, 392);
3471     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3472
3473     color = getPixelColor(device, 478, 298);
3474     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3475     color = getPixelColor(device, 482, 298);
3476     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3477     color = getPixelColor(device, 478, 302);
3478     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3479     color = getPixelColor(device, 482, 302);
3480     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3481
3482     color = getPixelColor(device, 478, 388);
3483     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3484     color = getPixelColor(device, 482, 388);
3485     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3486     color = getPixelColor(device, 478, 392);
3487     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3488     color = getPixelColor(device, 482, 392);
3489     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3490
3491     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3492     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3493     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3494      * Thus watch out if sampling from texels between 0 and 1.
3495      */
3496     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3497     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3498        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3499     if(!volume) {
3500         skip("Failed to create a volume texture\n");
3501         goto out;
3502     }
3503
3504     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3505     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3506     for(z = 0; z < 32; z++) {
3507         for(y = 0; y < 32; y++) {
3508             for(x = 0; x < 32; x++) {
3509                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3510                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3511                 float r_f = (float) x / 31.0;
3512                 float g_f = (float) y / 31.0;
3513                 float b_f = (float) z / 31.0;
3514
3515                 if(fmt == D3DFMT_A16B16G16R16) {
3516                     unsigned short *mem_s = mem;
3517                     mem_s[0]  = r_f * 65535.0;
3518                     mem_s[1]  = g_f * 65535.0;
3519                     mem_s[2]  = b_f * 65535.0;
3520                     mem_s[3]  = 65535;
3521                 } else {
3522                     unsigned char *mem_c = mem;
3523                     mem_c[0]  = b_f * 255.0;
3524                     mem_c[1]  = g_f * 255.0;
3525                     mem_c[2]  = r_f * 255.0;
3526                     mem_c[3]  = 255;
3527                 }
3528             }
3529         }
3530     }
3531     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3532     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3533
3534     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3535     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3536
3537     hr = IDirect3DDevice9_BeginScene(device);
3538     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3539     if(SUCCEEDED(hr))
3540     {
3541         float quad1[] = {
3542             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3543             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3544              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3545              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3546         };
3547         float quad2[] = {
3548             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3549             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3550              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3551              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3552         };
3553         float quad3[] = {
3554              0.0,       0.0,       0.1,     0.0,    0.0,
3555              0.0,       1.0,       0.1,     0.0,    0.0,
3556              1.0,       0.0,       0.1,     0.0,    0.0,
3557              1.0,       1.0,       0.1,     0.0,    0.0
3558         };
3559         float quad4[] = {
3560              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3561              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3562              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3563              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3564         };
3565         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3566                          0.0, 0.0, 1.0, 0.0,
3567                          0.0, 1.0, 0.0, 0.0,
3568                          0.0, 0.0, 0.0, 1.0};
3569         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3570         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3571
3572         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3573          * values
3574          */
3575         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3576         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3577         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3578         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3579         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3580         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3581
3582         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3583          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3584          * otherwise the w will be missing(blue).
3585          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3586          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3587          */
3588         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3589         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3590         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3591         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3592
3593         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3594         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3595         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3596         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3598         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3599         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3600         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3601         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3602
3603         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3604          * disable. ATI extends it up to the amount of values needed for the volume texture
3605          */
3606         memset(mat, 0, sizeof(mat));
3607         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3608         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3609         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3610         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3611         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3612         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3613         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3614         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3615
3616         hr = IDirect3DDevice9_EndScene(device);
3617         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3618     }
3619     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3621
3622     color = getPixelColor(device, 160, 360);
3623     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3624     color = getPixelColor(device, 160, 120);
3625     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3626        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3627     color = getPixelColor(device, 480, 120);
3628     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3629     color = getPixelColor(device, 480, 360);
3630     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3631
3632     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3633     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3634     hr = IDirect3DDevice9_BeginScene(device);
3635     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3636     if(SUCCEEDED(hr))
3637     {
3638         float quad1[] = {
3639             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3640             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3641              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3642              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3643         };
3644         float quad2[] = {
3645             -1.0,       0.0,       0.1,
3646             -1.0,       1.0,       0.1,
3647              0.0,       0.0,       0.1,
3648              0.0,       1.0,       0.1,
3649         };
3650         float quad3[] = {
3651              0.0,       0.0,       0.1,     1.0,
3652              0.0,       1.0,       0.1,     1.0,
3653              1.0,       0.0,       0.1,     1.0,
3654              1.0,       1.0,       0.1,     1.0
3655         };
3656         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3657                            0.0, 0.0, 0.0, 0.0,
3658                            0.0, 0.0, 0.0, 0.0,
3659                            0.0, 1.0, 0.0, 0.0};
3660         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3661                            1.0, 0.0, 0.0, 0.0,
3662                            0.0, 1.0, 0.0, 0.0,
3663                            0.0, 0.0, 1.0, 0.0};
3664         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3665         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3666
3667         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3668          */
3669         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3670         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3671         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3672         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3673         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3674         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3675
3676         /* None passed */
3677         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3678         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3680         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3682         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         /* 4 used, 1 passed */
3685         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3686         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3687         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3688         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3690         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3691
3692         hr = IDirect3DDevice9_EndScene(device);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3694     }
3695     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3696     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3697     color = getPixelColor(device, 160, 360);
3698     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3699     color = getPixelColor(device, 160, 120);
3700     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3701     color = getPixelColor(device, 480, 120);
3702     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3703     /* Quad4: unused */
3704
3705     IDirect3DVolumeTexture9_Release(volume);
3706
3707     out:
3708     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3709     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3710     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3711     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3712     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3713     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3714     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3715     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3716     IDirect3DVertexDeclaration9_Release(decl);
3717     IDirect3DVertexDeclaration9_Release(decl2);
3718     IDirect3DVertexDeclaration9_Release(decl3);
3719 }
3720
3721 static void texdepth_test(IDirect3DDevice9 *device)
3722 {
3723     IDirect3DPixelShader9 *shader;
3724     HRESULT hr;
3725     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3726     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3727     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3728     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3729     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3730     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3731     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3732     DWORD shader_code[] = {
3733         0xffff0104,                                                                 /* ps_1_4               */
3734         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3735         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3736         0x0000fffd,                                                                 /* phase                */
3737         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3738         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3739         0x0000ffff                                                                  /* end                  */
3740     };
3741     DWORD color;
3742     float vertex[] = {
3743        -1.0,   -1.0,    0.0,
3744         1.0,   -1.0,    1.0,
3745        -1.0,    1.0,    0.0,
3746         1.0,    1.0,    1.0
3747     };
3748
3749     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3751
3752     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3753     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3755     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3757     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3759     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3760     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3761
3762     /* Fill the depth buffer with a gradient */
3763     hr = IDirect3DDevice9_BeginScene(device);
3764     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3765     if(SUCCEEDED(hr))
3766     {
3767         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3768         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3769         hr = IDirect3DDevice9_EndScene(device);
3770         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3771     }
3772
3773     /* Now perform the actual tests. Same geometry, but with the shader */
3774     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3775     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3776     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3777     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3778     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3779     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3780
3781     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3782     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3783     hr = IDirect3DDevice9_BeginScene(device);
3784     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3785     if(SUCCEEDED(hr))
3786     {
3787         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3788         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3789
3790         hr = IDirect3DDevice9_EndScene(device);
3791         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3792     }
3793
3794     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3795     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3796     color = getPixelColor(device, 158, 240);
3797     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3798     color = getPixelColor(device, 162, 240);
3799     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3800
3801     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3802
3803     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3804     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3805     hr = IDirect3DDevice9_BeginScene(device);
3806     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3807     if(SUCCEEDED(hr))
3808     {
3809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3810         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3811
3812         hr = IDirect3DDevice9_EndScene(device);
3813         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3814     }
3815
3816     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3817     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3818     color = getPixelColor(device, 318, 240);
3819     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3820     color = getPixelColor(device, 322, 240);
3821     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3822
3823     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3824
3825     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3826     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3827     hr = IDirect3DDevice9_BeginScene(device);
3828     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3829     if(SUCCEEDED(hr))
3830     {
3831         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3832         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3833
3834         hr = IDirect3DDevice9_EndScene(device);
3835         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3836     }
3837     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3838     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3839
3840     color = getPixelColor(device, 1, 240);
3841     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3842
3843     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3844
3845     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3846     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3847     hr = IDirect3DDevice9_BeginScene(device);
3848     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3849     if(SUCCEEDED(hr))
3850     {
3851         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3852         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3853
3854         hr = IDirect3DDevice9_EndScene(device);
3855         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3856     }
3857     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3858     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3859     color = getPixelColor(device, 318, 240);
3860     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3861     color = getPixelColor(device, 322, 240);
3862     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3863
3864     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3865
3866     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3867     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3868     hr = IDirect3DDevice9_BeginScene(device);
3869     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3870     if(SUCCEEDED(hr))
3871     {
3872         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3873         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3874
3875         hr = IDirect3DDevice9_EndScene(device);
3876         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3877     }
3878     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3879     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3880
3881     color = getPixelColor(device, 1, 240);
3882     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3883
3884     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3885
3886     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3887     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3888     hr = IDirect3DDevice9_BeginScene(device);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3890     if(SUCCEEDED(hr))
3891     {
3892         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3893         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3894
3895         hr = IDirect3DDevice9_EndScene(device);
3896         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3897     }
3898     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3899     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3900
3901     color = getPixelColor(device, 638, 240);
3902     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3903
3904     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3905
3906     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3907     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3908     hr = IDirect3DDevice9_BeginScene(device);
3909     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3910     if(SUCCEEDED(hr))
3911     {
3912         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3913         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3914
3915         hr = IDirect3DDevice9_EndScene(device);
3916         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3917     }
3918     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3919     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3920
3921     color = getPixelColor(device, 638, 240);
3922     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3923
3924     /* Cleanup */
3925     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3926     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3927     IDirect3DPixelShader9_Release(shader);
3928
3929     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3930     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3931     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3932     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3933 }
3934
3935 static void texkill_test(IDirect3DDevice9 *device)
3936 {
3937     IDirect3DPixelShader9 *shader;
3938     HRESULT hr;
3939     DWORD color;
3940
3941     const float vertex[] = {
3942     /*                          bottom  top    right    left */
3943         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
3944          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
3945         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
3946          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
3947     };
3948
3949     DWORD shader_code_11[] = {
3950     0xffff0101,                                                             /* ps_1_1                     */
3951     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3952     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
3953     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
3954     0x0000ffff                                                              /* end                        */
3955     };
3956     DWORD shader_code_20[] = {
3957     0xffff0200,                                                             /* ps_2_0                     */
3958     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
3959     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3960     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
3961     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
3962     0x0000ffff                                                              /* end                        */
3963     };
3964
3965     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3966     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3967     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3968     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3969
3970     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3971     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3972     hr = IDirect3DDevice9_BeginScene(device);
3973     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3974     if(SUCCEEDED(hr))
3975     {
3976         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3977         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3978         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3979         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3980         hr = IDirect3DDevice9_EndScene(device);
3981         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3982     }
3983     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3984     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3985     color = getPixelColor(device, 63, 46);
3986     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3987     color = getPixelColor(device, 66, 46);
3988     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3989     color = getPixelColor(device, 63, 49);
3990     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3991     color = getPixelColor(device, 66, 49);
3992     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3993
3994     color = getPixelColor(device, 578, 46);
3995     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3996     color = getPixelColor(device, 575, 46);
3997     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3998     color = getPixelColor(device, 578, 49);
3999     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4000     color = getPixelColor(device, 575, 49);
4001     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4002
4003     color = getPixelColor(device, 63, 430);
4004     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4005     color = getPixelColor(device, 63, 433);
4006     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4007     color = getPixelColor(device, 66, 433);
4008     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4009     color = getPixelColor(device, 66, 430);
4010     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4011
4012     color = getPixelColor(device, 578, 430);
4013     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4014     color = getPixelColor(device, 578, 433);
4015     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4016     color = getPixelColor(device, 575, 433);
4017     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4018     color = getPixelColor(device, 575, 430);
4019     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4020
4021     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4022     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4023     IDirect3DPixelShader9_Release(shader);
4024
4025     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4026     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4027     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4028     if(FAILED(hr)) {
4029         skip("Failed to create 2.0 test shader, most likely not supported\n");
4030         return;
4031     }
4032
4033     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4034     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4035     hr = IDirect3DDevice9_BeginScene(device);
4036     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4037     if(SUCCEEDED(hr))
4038     {
4039         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4040         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4041         hr = IDirect3DDevice9_EndScene(device);
4042         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4043     }
4044     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4045
4046     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4047     color = getPixelColor(device, 63, 46);
4048     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4049     color = getPixelColor(device, 66, 46);
4050     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4051     color = getPixelColor(device, 63, 49);
4052     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4053     color = getPixelColor(device, 66, 49);
4054     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4055
4056     color = getPixelColor(device, 578, 46);
4057     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4058     color = getPixelColor(device, 575, 46);
4059     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4060     color = getPixelColor(device, 578, 49);
4061     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4062     color = getPixelColor(device, 575, 49);
4063     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4064
4065     color = getPixelColor(device, 63, 430);
4066     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4067     color = getPixelColor(device, 63, 433);
4068     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4069     color = getPixelColor(device, 66, 433);
4070     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4071     color = getPixelColor(device, 66, 430);
4072     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4073
4074     color = getPixelColor(device, 578, 430);
4075     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4076     color = getPixelColor(device, 578, 433);
4077     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4078     color = getPixelColor(device, 575, 433);
4079     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4080     color = getPixelColor(device, 575, 430);
4081     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4082
4083     /* Cleanup */
4084     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4085     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4086     IDirect3DPixelShader9_Release(shader);
4087 }
4088
4089 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4090 {
4091     IDirect3D9 *d3d9;
4092     HRESULT hr;
4093     IDirect3DTexture9 *texture;
4094     IDirect3DPixelShader9 *shader;
4095     IDirect3DPixelShader9 *shader2;
4096     D3DLOCKED_RECT lr;
4097     DWORD color;
4098     DWORD shader_code[] = {
4099         0xffff0101,                             /* ps_1_1       */
4100         0x00000042, 0xb00f0000,                 /* tex t0       */
4101         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4102         0x0000ffff                              /* end          */
4103     };
4104     DWORD shader_code2[] = {
4105         0xffff0101,                             /* ps_1_1       */
4106         0x00000042, 0xb00f0000,                 /* tex t0       */
4107         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4108         0x0000ffff                              /* end          */
4109     };
4110
4111     float quad[] = {
4112        -1.0,   -1.0,   0.1,     0.5,    0.5,
4113         1.0,   -1.0,   0.1,     0.5,    0.5,
4114        -1.0,    1.0,   0.1,     0.5,    0.5,
4115         1.0,    1.0,   0.1,     0.5,    0.5,
4116     };
4117
4118     memset(&lr, 0, sizeof(lr));
4119     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4120     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4121                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4122     IDirect3D9_Release(d3d9);
4123     if(FAILED(hr)) {
4124         skip("No D3DFMT_X8L8V8U8 support\n");
4125     };
4126
4127     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4128     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4129
4130     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4132     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4133     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4134     *((DWORD *) lr.pBits) = 0x11ca3141;
4135     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4136     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4137
4138     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4139     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4140     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4141     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4142
4143     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4145     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4147     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4149
4150     hr = IDirect3DDevice9_BeginScene(device);
4151     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4152     if(SUCCEEDED(hr))
4153     {
4154         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4155         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4156
4157         hr = IDirect3DDevice9_EndScene(device);
4158         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4159     }
4160     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4161     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4162     color = getPixelColor(device, 578, 430);
4163     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4164        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4165
4166     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4167     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4168     hr = IDirect3DDevice9_BeginScene(device);
4169     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4170     if(SUCCEEDED(hr))
4171     {
4172         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4173         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4174
4175         hr = IDirect3DDevice9_EndScene(device);
4176         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4177     }
4178     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4179     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4180     color = getPixelColor(device, 578, 430);
4181     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4182
4183     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4184     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4185     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4186     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4187     IDirect3DPixelShader9_Release(shader);
4188     IDirect3DPixelShader9_Release(shader2);
4189     IDirect3DTexture9_Release(texture);
4190 }
4191
4192 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4193 {
4194     HRESULT hr;
4195     IDirect3D9 *d3d;
4196     IDirect3DTexture9 *texture = NULL;
4197     IDirect3DSurface9 *surface;
4198     DWORD color;
4199     const RECT r1 = {256, 256, 512, 512};
4200     const RECT r2 = {512, 256, 768, 512};
4201     const RECT r3 = {256, 512, 512, 768};
4202     const RECT r4 = {512, 512, 768, 768};
4203     unsigned int x, y;
4204     D3DLOCKED_RECT lr;
4205     memset(&lr, 0, sizeof(lr));
4206
4207     IDirect3DDevice9_GetDirect3D(device, &d3d);
4208     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4209        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4210         skip("No autogenmipmap support\n");
4211         IDirect3D9_Release(d3d);
4212         return;
4213     }
4214     IDirect3D9_Release(d3d);
4215
4216     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4217     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4218
4219     /* Make the mipmap big, so that a smaller mipmap is used
4220      */
4221     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4222                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4223     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4224
4225     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4226     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4227     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4228     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4229     for(y = 0; y < 1024; y++) {
4230         for(x = 0; x < 1024; x++) {
4231             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4232             POINT pt;
4233
4234             pt.x = x;
4235             pt.y = y;
4236             if(PtInRect(&r1, pt)) {
4237                 *dst = 0xffff0000;
4238             } else if(PtInRect(&r2, pt)) {
4239                 *dst = 0xff00ff00;
4240             } else if(PtInRect(&r3, pt)) {
4241                 *dst = 0xff0000ff;
4242             } else if(PtInRect(&r4, pt)) {
4243                 *dst = 0xff000000;
4244             } else {
4245                 *dst = 0xffffffff;
4246             }
4247         }
4248     }
4249     hr = IDirect3DSurface9_UnlockRect(surface);
4250     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4251     IDirect3DSurface9_Release(surface);
4252
4253     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4254     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4255     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4256     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4257
4258     hr = IDirect3DDevice9_BeginScene(device);
4259     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4260     if(SUCCEEDED(hr)) {
4261         const float quad[] =  {
4262            -0.5,   -0.5,    0.1,    0.0,    0.0,
4263            -0.5,    0.5,    0.1,    0.0,    1.0,
4264             0.5,   -0.5,    0.1,    1.0,    0.0,
4265             0.5,    0.5,    0.1,    1.0,    1.0
4266         };
4267
4268         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4269         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4270         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4271         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4272         hr = IDirect3DDevice9_EndScene(device);
4273         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4274     }
4275     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4276     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4277     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4278     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4279     IDirect3DTexture9_Release(texture);
4280
4281     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4282     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4283     color = getPixelColor(device, 200, 200);
4284     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4285     color = getPixelColor(device, 280, 200);
4286     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4287     color = getPixelColor(device, 360, 200);
4288     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4289     color = getPixelColor(device, 440, 200);
4290     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4291     color = getPixelColor(device, 200, 270);
4292     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4293     color = getPixelColor(device, 280, 270);
4294     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4295     color = getPixelColor(device, 360, 270);
4296     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4297     color = getPixelColor(device, 440, 270);
4298     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4299 }
4300
4301 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4302 {
4303     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4304     IDirect3DVertexDeclaration9 *decl;
4305     HRESULT hr;
4306     DWORD color;
4307     DWORD shader_code_11[] =  {
4308         0xfffe0101,                                         /* vs_1_1           */
4309         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4310         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4311         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4312         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4313         0x0000ffff                                          /* end              */
4314     };
4315     DWORD shader_code_11_2[] =  {
4316         0xfffe0101,                                         /* vs_1_1           */
4317         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4318         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4319         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4320         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4321         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4322         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4323         0x0000ffff                                          /* end              */
4324     };
4325     DWORD shader_code_20[] =  {
4326         0xfffe0200,                                         /* vs_2_0           */
4327         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4328         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4329         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4330         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4331         0x0000ffff                                          /* end              */
4332     };
4333     DWORD shader_code_20_2[] =  {
4334         0xfffe0200,                                         /* vs_2_0           */
4335         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4336         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4337         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4338         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4339         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4340         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4341         0x0000ffff                                          /* end              */
4342     };
4343     static const D3DVERTEXELEMENT9 decl_elements[] = {
4344         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4345         D3DDECL_END()
4346     };
4347     float quad1[] = {
4348         -1.0,   -1.0,   0.1,
4349          0.0,   -1.0,   0.1,
4350         -1.0,    0.0,   0.1,
4351          0.0,    0.0,   0.1
4352     };
4353     float quad2[] = {
4354          0.0,   -1.0,   0.1,
4355          1.0,   -1.0,   0.1,
4356          0.0,    0.0,   0.1,
4357          1.0,    0.0,   0.1
4358     };
4359     float quad3[] = {
4360          0.0,    0.0,   0.1,
4361          1.0,    0.0,   0.1,
4362          0.0,    1.0,   0.1,
4363          1.0,    1.0,   0.1
4364     };
4365     float quad4[] = {
4366         -1.0,    0.0,   0.1,
4367          0.0,    0.0,   0.1,
4368         -1.0,    1.0,   0.1,
4369          0.0,    1.0,   0.1
4370     };
4371     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4372     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4373
4374     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4375     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4376
4377     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4378     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4379     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4380     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4381     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4382     if(FAILED(hr)) shader_20 = NULL;
4383     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4384     if(FAILED(hr)) shader_20_2 = NULL;
4385     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4386     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4387
4388     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4389     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4390     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4391     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4392     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4393     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4394
4395     hr = IDirect3DDevice9_BeginScene(device);
4396     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4397     if(SUCCEEDED(hr))
4398     {
4399         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4400         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4401         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4402         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4403
4404         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4405         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4406         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4407         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4408
4409         if(shader_20) {
4410             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4411             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4412             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4413             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4414         }
4415
4416         if(shader_20_2) {
4417             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4418             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4419             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4420             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4421         }
4422
4423         hr = IDirect3DDevice9_EndScene(device);
4424         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4425     }
4426     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4427     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4428
4429     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4430     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4431     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4432     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4433
4434     color = getPixelColor(device, 160, 360);
4435     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4436        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4437     color = getPixelColor(device, 480, 360);
4438     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4439        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4440     if(shader_20) {
4441         color = getPixelColor(device, 160, 120);
4442         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4443            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4444     }
4445     if(shader_20_2) {
4446         color = getPixelColor(device, 480, 120);
4447         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4448            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4449     }
4450
4451     IDirect3DVertexDeclaration9_Release(decl);
4452     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4453     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4454     IDirect3DVertexShader9_Release(shader_11_2);
4455     IDirect3DVertexShader9_Release(shader_11);
4456 }
4457
4458 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4459 {
4460     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4461     HRESULT hr;
4462     DWORD color;
4463     DWORD shader_code_11[] =  {
4464         0xffff0101,                                         /* ps_1_1           */
4465         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4466         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4467         0x0000ffff                                          /* end              */
4468     };
4469     DWORD shader_code_12[] =  {
4470         0xffff0102,                                         /* ps_1_2           */
4471         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4472         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4473         0x0000ffff                                          /* end              */
4474     };
4475     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4476      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4477      * During development of this test, 1.3 shaders were verified too
4478      */
4479     DWORD shader_code_14[] =  {
4480         0xffff0104,                                         /* ps_1_4           */
4481         /* Try to make one constant local. It gets clamped too, although the binary contains
4482          * the bigger numbers
4483          */
4484         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4485         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4486         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4487         0x0000ffff                                          /* end              */
4488     };
4489     DWORD shader_code_20[] =  {
4490         0xffff0200,                                         /* ps_2_0           */
4491         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4492         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4493         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4494         0x0000ffff                                          /* end              */
4495     };
4496     float quad1[] = {
4497         -1.0,   -1.0,   0.1,
4498          0.0,   -1.0,   0.1,
4499         -1.0,    0.0,   0.1,
4500          0.0,    0.0,   0.1
4501     };
4502     float quad2[] = {
4503          0.0,   -1.0,   0.1,
4504          1.0,   -1.0,   0.1,
4505          0.0,    0.0,   0.1,
4506          1.0,    0.0,   0.1
4507     };
4508     float quad3[] = {
4509          0.0,    0.0,   0.1,
4510          1.0,    0.0,   0.1,
4511          0.0,    1.0,   0.1,
4512          1.0,    1.0,   0.1
4513     };
4514     float quad4[] = {
4515         -1.0,    0.0,   0.1,
4516          0.0,    0.0,   0.1,
4517         -1.0,    1.0,   0.1,
4518          0.0,    1.0,   0.1
4519     };
4520     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4521     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4522
4523     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4524     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4525
4526     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4527     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4528     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4529     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4530     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4531     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4532     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4533     if(FAILED(hr)) shader_20 = NULL;
4534
4535     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4536     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4537     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4538     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4539     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4541
4542     hr = IDirect3DDevice9_BeginScene(device);
4543     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4544     if(SUCCEEDED(hr))
4545     {
4546         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4547         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4548         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4549         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4550
4551         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4552         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4553         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4554         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4555
4556         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4557         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4558         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4559         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4560
4561         if(shader_20) {
4562             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4563             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4564             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4565             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4566         }
4567
4568         hr = IDirect3DDevice9_EndScene(device);
4569         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4570     }
4571     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4573
4574     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4576
4577     color = getPixelColor(device, 160, 360);
4578     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4579        "quad 1 has color %08x, expected 0x00808000\n", color);
4580     color = getPixelColor(device, 480, 360);
4581     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4582        "quad 2 has color %08x, expected 0x00808000\n", color);
4583     color = getPixelColor(device, 480, 120);
4584     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4585        "quad 3 has color %08x, expected 0x00808000\n", color);
4586     if(shader_20) {
4587         color = getPixelColor(device, 160, 120);
4588         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4589            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4590     }
4591
4592     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4593     IDirect3DPixelShader9_Release(shader_14);
4594     IDirect3DPixelShader9_Release(shader_12);
4595     IDirect3DPixelShader9_Release(shader_11);
4596 }
4597
4598 static void dp2add_ps_test(IDirect3DDevice9 *device)
4599 {
4600     IDirect3DPixelShader9 *shader_dp2add = NULL;
4601     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4602     HRESULT hr;
4603     DWORD color;
4604
4605     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4606      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4607      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4608      * r0 first.
4609      * The result here for the r,g,b components should be roughly 0.5:
4610      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4611     static const DWORD shader_code_dp2add[] =  {
4612         0xffff0200,                                                             /* ps_2_0                       */
4613         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4614
4615         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4616         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4617
4618         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4619         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4620         0x0000ffff                                                              /* end                          */
4621     };
4622
4623     /* Test the _sat modifier, too.  Result here should be:
4624      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4625      *      _SAT: ==> 1.0
4626      *   ADD: (1.0 + -0.5) = 0.5
4627      */
4628     static const DWORD shader_code_dp2add_sat[] =  {
4629         0xffff0200,                                                             /* ps_2_0                           */
4630         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4631
4632         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4633         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4634         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4635
4636         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4637         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4638         0x0000ffff                                                              /* end                              */
4639     };
4640
4641     const float quad[] = {
4642         -1.0,   -1.0,   0.1,
4643          1.0,   -1.0,   0.1,
4644         -1.0,    1.0,   0.1,
4645          1.0,    1.0,   0.1
4646     };
4647
4648
4649     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4650     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4651
4652     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4653     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4654
4655     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4656     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4657
4658     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4659     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4660
4661     if (shader_dp2add) {
4662
4663         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4664         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4665
4666         hr = IDirect3DDevice9_BeginScene(device);
4667         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4668         if(SUCCEEDED(hr))
4669         {
4670             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4671             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4672
4673             hr = IDirect3DDevice9_EndScene(device);
4674             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4675         }
4676         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4677         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4678
4679         color = getPixelColor(device, 360, 240);
4680         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4681                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4682
4683         IDirect3DPixelShader9_Release(shader_dp2add);
4684     } else {
4685         skip("dp2add shader creation failed\n");
4686     }
4687
4688     if (shader_dp2add_sat) {
4689
4690         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4691         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4692
4693         hr = IDirect3DDevice9_BeginScene(device);
4694         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4695         if(SUCCEEDED(hr))
4696         {
4697             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4698             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4699
4700             hr = IDirect3DDevice9_EndScene(device);
4701             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4702         }
4703         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4704         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4705
4706         color = getPixelColor(device, 360, 240);
4707         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4708                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4709
4710         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4711     } else {
4712         skip("dp2add shader creation failed\n");
4713     }
4714
4715     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4716     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4717 }
4718
4719 static void cnd_test(IDirect3DDevice9 *device)
4720 {
4721     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4722     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4723     HRESULT hr;
4724     DWORD color;
4725     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4726      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4727      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4728      */
4729     DWORD shader_code_11[] =  {
4730         0xffff0101,                                                                 /* ps_1_1               */
4731         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4732         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4733         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4734         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4735         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4736         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4737         0x0000ffff                                                                  /* end                  */
4738     };
4739     DWORD shader_code_12[] =  {
4740         0xffff0102,                                                                 /* ps_1_2               */
4741         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4742         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4743         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4744         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4745         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4746         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4747         0x0000ffff                                                                  /* end                  */
4748     };
4749     DWORD shader_code_13[] =  {
4750         0xffff0103,                                                                 /* ps_1_3               */
4751         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4752         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4753         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4754         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4755         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4756         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4757         0x0000ffff                                                                  /* end                  */
4758     };
4759     DWORD shader_code_14[] =  {
4760         0xffff0104,                                                                 /* ps_1_3               */
4761         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4762         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4763         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4764         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4765         0x0000ffff                                                                  /* end                  */
4766     };
4767
4768     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4769      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4770      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4771      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4772      * native CreatePixelShader returns an error.
4773      *
4774      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4775      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4776      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4777      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4778      */
4779     DWORD shader_code_11_coissue[] =  {
4780         0xffff0101,                                                             /* ps_1_1                   */
4781         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4782         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4783         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4784         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4785         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4786         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4787         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4788         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4789         /* 0x40000000 = D3DSI_COISSUE */
4790         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4791         0x0000ffff                                                              /* end                      */
4792     };
4793     DWORD shader_code_12_coissue[] =  {
4794         0xffff0102,                                                             /* ps_1_2                   */
4795         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4796         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4797         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4798         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4799         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4800         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4801         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4802         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4803         /* 0x40000000 = D3DSI_COISSUE */
4804         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4805         0x0000ffff                                                              /* end                      */
4806     };
4807     DWORD shader_code_13_coissue[] =  {
4808         0xffff0103,                                                             /* ps_1_3                   */
4809         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4810         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4811         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4812         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4813         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4814         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4815         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4816         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4817         /* 0x40000000 = D3DSI_COISSUE */
4818         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4819         0x0000ffff                                                              /* end                      */
4820     };
4821     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4822      * compare against 0.5
4823      */
4824     DWORD shader_code_14_coissue[] =  {
4825         0xffff0104,                                                             /* ps_1_4                   */
4826         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4827         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4828         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4829         /* 0x40000000 = D3DSI_COISSUE */
4830         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4831         0x0000ffff                                                              /* end                      */
4832     };
4833     float quad1[] = {
4834         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4835          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4836         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4837          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4838     };
4839     float quad2[] = {
4840          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4841          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4842          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4843          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4844     };
4845     float quad3[] = {
4846          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4847          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4848          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4849          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4850     };
4851     float quad4[] = {
4852         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4853          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4854         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4855          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4856     };
4857     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4858     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4859     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4860     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4861
4862     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4863     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4864
4865     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4866     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4867     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4868     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4869     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4870     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4871     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4872     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4873     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4874     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4875     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4876     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4877     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4879     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4880     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4881
4882     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4883     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4884     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4885     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4886     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4887     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4888
4889     hr = IDirect3DDevice9_BeginScene(device);
4890     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4891     if(SUCCEEDED(hr))
4892     {
4893         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4894         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4895         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4896         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4897
4898         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4899         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4900         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4901         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4902
4903         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4904         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4905         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4906         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4907
4908         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4909         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4910         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4911         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4912
4913         hr = IDirect3DDevice9_EndScene(device);
4914         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4915     }
4916     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4917     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4918
4919     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4920     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4921
4922     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4923     color = getPixelColor(device, 158, 118);
4924     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4925     color = getPixelColor(device, 162, 118);
4926     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4927     color = getPixelColor(device, 158, 122);
4928     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4929     color = getPixelColor(device, 162, 122);
4930     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4931
4932     /* 1.1 shader. All 3 components get set, based on the .w comparison */
4933     color = getPixelColor(device, 158, 358);
4934     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4935     color = getPixelColor(device, 162, 358);
4936     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4937         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4938     color = getPixelColor(device, 158, 362);
4939     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4940     color = getPixelColor(device, 162, 362);
4941     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4942         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4943
4944     /* 1.2 shader */
4945     color = getPixelColor(device, 478, 358);
4946     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4947     color = getPixelColor(device, 482, 358);
4948     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4949         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4950     color = getPixelColor(device, 478, 362);
4951     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4952     color = getPixelColor(device, 482, 362);
4953     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4954         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4955
4956     /* 1.3 shader */
4957     color = getPixelColor(device, 478, 118);
4958     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4959     color = getPixelColor(device, 482, 118);
4960     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4961         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4962     color = getPixelColor(device, 478, 122);
4963     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4964     color = getPixelColor(device, 482, 122);
4965     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4966         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4967
4968     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4969     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4970     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4971     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4972     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4973     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4974
4975     hr = IDirect3DDevice9_BeginScene(device);
4976     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4977     if(SUCCEEDED(hr))
4978     {
4979         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4980         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4981         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4982         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4983
4984         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4985         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4988
4989         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4990         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4991         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4992         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4993
4994         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4995         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4996         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4997         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4998
4999         hr = IDirect3DDevice9_EndScene(device);
5000         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5001     }
5002     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5003     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5004
5005     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5006     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5007
5008     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5009      * that we swapped the values in c1 and c2 to make the other tests return some color
5010      */
5011     color = getPixelColor(device, 158, 118);
5012     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5013     color = getPixelColor(device, 162, 118);
5014     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5015     color = getPixelColor(device, 158, 122);
5016     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5017     color = getPixelColor(device, 162, 122);
5018     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5019
5020     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5021     color = getPixelColor(device, 158, 358);
5022     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5023         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5024     color = getPixelColor(device, 162, 358);
5025     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5026         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5027     color = getPixelColor(device, 158, 362);
5028     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5029         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5030     color = getPixelColor(device, 162, 362);
5031     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5032         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5033
5034     /* 1.2 shader */
5035     color = getPixelColor(device, 478, 358);
5036     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5037         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5038     color = getPixelColor(device, 482, 358);
5039     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5040         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5041     color = getPixelColor(device, 478, 362);
5042     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5043         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5044     color = getPixelColor(device, 482, 362);
5045     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5046         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5047
5048     /* 1.3 shader */
5049     color = getPixelColor(device, 478, 118);
5050     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5051         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5052     color = getPixelColor(device, 482, 118);
5053     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5054         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5055     color = getPixelColor(device, 478, 122);
5056     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5057         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5058     color = getPixelColor(device, 482, 122);
5059     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5060         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5061
5062     IDirect3DPixelShader9_Release(shader_14_coissue);
5063     IDirect3DPixelShader9_Release(shader_13_coissue);
5064     IDirect3DPixelShader9_Release(shader_12_coissue);
5065     IDirect3DPixelShader9_Release(shader_11_coissue);
5066     IDirect3DPixelShader9_Release(shader_14);
5067     IDirect3DPixelShader9_Release(shader_13);
5068     IDirect3DPixelShader9_Release(shader_12);
5069     IDirect3DPixelShader9_Release(shader_11);
5070 }
5071
5072 static void nested_loop_test(IDirect3DDevice9 *device) {
5073     const DWORD shader_code[] = {
5074         0xffff0300,                                                             /* ps_3_0               */
5075         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5076         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5077         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5078         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5079         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5080         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5081         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5082         0x0000001d,                                                             /* endloop              */
5083         0x0000001d,                                                             /* endloop              */
5084         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5085         0x0000ffff                                                              /* end                  */
5086     };
5087     IDirect3DPixelShader9 *shader;
5088     HRESULT hr;
5089     DWORD color;
5090     const float quad[] = {
5091         -1.0,   -1.0,   0.1,
5092          1.0,   -1.0,   0.1,
5093         -1.0,    1.0,   0.1,
5094          1.0,    1.0,   0.1
5095     };
5096
5097     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5098     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5099     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5100     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5101     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5102     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5104     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5105
5106     hr = IDirect3DDevice9_BeginScene(device);
5107     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5108     if(SUCCEEDED(hr))
5109     {
5110         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5111         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5112         hr = IDirect3DDevice9_EndScene(device);
5113         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5114     }
5115     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5116     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5117
5118     color = getPixelColor(device, 360, 240);
5119     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5120        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5121
5122     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5123     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5124     IDirect3DPixelShader9_Release(shader);
5125 }
5126
5127 struct varying_test_struct
5128 {
5129     const DWORD             *shader_code;
5130     IDirect3DPixelShader9   *shader;
5131     DWORD                   color, color_rhw;
5132     const char              *name;
5133     BOOL                    todo, todo_rhw;
5134 };
5135
5136 struct hugeVertex
5137 {
5138     float pos_x,        pos_y,      pos_z,      rhw;
5139     float weight_1,     weight_2,   weight_3,   weight_4;
5140     float index_1,      index_2,    index_3,    index_4;
5141     float normal_1,     normal_2,   normal_3,   normal_4;
5142     float fog_1,        fog_2,      fog_3,      fog_4;
5143     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5144     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5145     float binormal_1,   binormal_2, binormal_3, binormal_4;
5146     float depth_1,      depth_2,    depth_3,    depth_4;
5147     DWORD diffuse, specular;
5148 };
5149
5150 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5151     /* dcl_position: fails to compile */
5152     const DWORD blendweight_code[] = {
5153         0xffff0300,                             /* ps_3_0                   */
5154         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5155         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5156         0x0000ffff                              /* end                      */
5157     };
5158     const DWORD blendindices_code[] = {
5159         0xffff0300,                             /* ps_3_0                   */
5160         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5161         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5162         0x0000ffff                              /* end                      */
5163     };
5164     const DWORD normal_code[] = {
5165         0xffff0300,                             /* ps_3_0                   */
5166         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5167         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5168         0x0000ffff                              /* end                      */
5169     };
5170     /* psize: fails? */
5171     const DWORD texcoord0_code[] = {
5172         0xffff0300,                             /* ps_3_0                   */
5173         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5174         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5175         0x0000ffff                              /* end                      */
5176     };
5177     const DWORD tangent_code[] = {
5178         0xffff0300,                             /* ps_3_0                   */
5179         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5180         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5181         0x0000ffff                              /* end                      */
5182     };
5183     const DWORD binormal_code[] = {
5184         0xffff0300,                             /* ps_3_0                   */
5185         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5186         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5187         0x0000ffff                              /* end                      */
5188     };
5189     /* tessfactor: fails */
5190     /* positiont: fails */
5191     const DWORD color_code[] = {
5192         0xffff0300,                             /* ps_3_0                   */
5193         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5194         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5195         0x0000ffff                              /* end                      */
5196     };
5197     const DWORD fog_code[] = {
5198         0xffff0300,                             /* ps_3_0                   */
5199         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5200         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5201         0x0000ffff                              /* end                      */
5202     };
5203     const DWORD depth_code[] = {
5204         0xffff0300,                             /* ps_3_0                   */
5205         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5206         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5207         0x0000ffff                              /* end                      */
5208     };
5209     const DWORD specular_code[] = {
5210         0xffff0300,                             /* ps_3_0                   */
5211         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5212         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5213         0x0000ffff                              /* end                      */
5214     };
5215     /* sample: fails */
5216
5217     struct varying_test_struct tests[] = {
5218        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5219        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5220        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5221        /* Why does dx not forward the texcoord? */
5222        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5223        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5224        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5225        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5226        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5227        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5228        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5229     };
5230     /* Declare a monster vertex type :-) */
5231     static const D3DVERTEXELEMENT9 decl_elements[] = {
5232         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5233         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5234         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5235         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5236         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5237         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5238         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5239         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5240         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5241         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5242         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5243         D3DDECL_END()
5244     };
5245     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5246         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5247         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5248         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5249         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5250         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5251         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5252         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5253         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5254         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5255         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5256         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5257         D3DDECL_END()
5258     };
5259     struct hugeVertex data[4] = {
5260         {
5261             -1.0,   -1.0,   0.1,    1.0,
5262              0.1,    0.1,   0.1,    0.1,
5263              0.2,    0.2,   0.2,    0.2,
5264              0.3,    0.3,   0.3,    0.3,
5265              0.4,    0.4,   0.4,    0.4,
5266              0.50,   0.55,  0.55,   0.55,
5267              0.6,    0.6,   0.6,    0.7,
5268              0.7,    0.7,   0.7,    0.6,
5269              0.8,    0.8,   0.8,    0.8,
5270              0xe6e6e6e6, /* 0.9 * 256 */
5271              0x224488ff  /* Nothing special */
5272         },
5273         {
5274              1.0,   -1.0,   0.1,    1.0,
5275              0.1,    0.1,   0.1,    0.1,
5276              0.2,    0.2,   0.2,    0.2,
5277              0.3,    0.3,   0.3,    0.3,
5278              0.4,    0.4,   0.4,    0.4,
5279              0.50,   0.55,  0.55,   0.55,
5280              0.6,    0.6,   0.6,    0.7,
5281              0.7,    0.7,   0.7,    0.6,
5282              0.8,    0.8,   0.8,    0.8,
5283              0xe6e6e6e6, /* 0.9 * 256 */
5284              0x224488ff /* Nothing special */
5285         },
5286         {
5287             -1.0,    1.0,   0.1,    1.0,
5288              0.1,    0.1,   0.1,    0.1,
5289              0.2,    0.2,   0.2,    0.2,
5290              0.3,    0.3,   0.3,    0.3,
5291              0.4,    0.4,   0.4,    0.4,
5292              0.50,   0.55,  0.55,   0.55,
5293              0.6,    0.6,   0.6,    0.7,
5294              0.7,    0.7,   0.7,    0.6,
5295              0.8,    0.8,   0.8,    0.8,
5296              0xe6e6e6e6, /* 0.9 * 256 */
5297              0x224488ff /* Nothing special */
5298         },
5299         {
5300              1.0,    1.0,   0.1,    1.0,
5301              0.1,    0.1,   0.1,    0.1,
5302              0.2,    0.2,   0.2,    0.2,
5303              0.3,    0.3,   0.3,    0.3,
5304              0.4,    0.4,   0.4,    0.4,
5305              0.50,   0.55,  0.55,   0.55,
5306              0.6,    0.6,   0.6,    0.7,
5307              0.7,    0.7,   0.7,    0.6,
5308              0.8,    0.8,   0.8,    0.8,
5309              0xe6e6e6e6, /* 0.9 * 256 */
5310              0x224488ff /* Nothing special */
5311         },
5312     };
5313     struct hugeVertex data2[4];
5314     IDirect3DVertexDeclaration9 *decl;
5315     IDirect3DVertexDeclaration9 *decl2;
5316     HRESULT hr;
5317     unsigned int i;
5318     DWORD color, r, g, b, r_e, g_e, b_e;
5319     BOOL drawok;
5320
5321     memcpy(data2, data, sizeof(data2));
5322     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5323     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5324     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5325     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5326
5327     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5328     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5329     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5330     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5331     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5332     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5333
5334     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5335     {
5336         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5337         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5338            tests[i].name, hr);
5339     }
5340
5341     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5342     {
5343         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5344         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5345
5346         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5347         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5348
5349         hr = IDirect3DDevice9_BeginScene(device);
5350         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5351         drawok = FALSE;
5352         if(SUCCEEDED(hr))
5353         {
5354             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5355             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5356             drawok = SUCCEEDED(hr);
5357             hr = IDirect3DDevice9_EndScene(device);
5358             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5359         }
5360         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5361         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5362
5363         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5364          * the failure and do not check the color if it failed
5365          */
5366         if(!drawok) {
5367             continue;
5368         }
5369
5370         color = getPixelColor(device, 360, 240);
5371         r = color & 0x00ff0000 >> 16;
5372         g = color & 0x0000ff00 >>  8;
5373         b = color & 0x000000ff;
5374         r_e = tests[i].color & 0x00ff0000 >> 16;
5375         g_e = tests[i].color & 0x0000ff00 >>  8;
5376         b_e = tests[i].color & 0x000000ff;
5377
5378         if(tests[i].todo) {
5379             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5380                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5381                          tests[i].name, color, tests[i].color);
5382         } else {
5383             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5384                "Test %s returned color 0x%08x, expected 0x%08x\n",
5385                tests[i].name, color, tests[i].color);
5386         }
5387     }
5388
5389     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5390     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5391     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5392     {
5393         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5394         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5395
5396         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5397         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5398
5399         hr = IDirect3DDevice9_BeginScene(device);
5400         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5401         if(SUCCEEDED(hr))
5402         {
5403             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5404             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5405             hr = IDirect3DDevice9_EndScene(device);
5406             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5407         }
5408         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5409         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5410
5411         color = getPixelColor(device, 360, 240);
5412         r = color & 0x00ff0000 >> 16;
5413         g = color & 0x0000ff00 >>  8;
5414         b = color & 0x000000ff;
5415         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5416         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5417         b_e = tests[i].color_rhw & 0x000000ff;
5418
5419         if(tests[i].todo_rhw) {
5420             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5421              * pipeline
5422              */
5423             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5424                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5425                          tests[i].name, color, tests[i].color_rhw);
5426         } else {
5427             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5428                "Test %s returned color 0x%08x, expected 0x%08x\n",
5429                tests[i].name, color, tests[i].color_rhw);
5430         }
5431     }
5432
5433     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5434     {
5435         IDirect3DPixelShader9_Release(tests[i].shader);
5436     }
5437
5438     IDirect3DVertexDeclaration9_Release(decl2);
5439     IDirect3DVertexDeclaration9_Release(decl);
5440 }
5441
5442 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5443     static const DWORD ps_code[] = {
5444     0xffff0300,                                                             /* ps_3_0                       */
5445     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5446     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5447     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5448     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5449     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5450     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5451     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5452     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5453     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5454
5455     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5456     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5457     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5458     0x0000001d,                                                             /* endloop                      */
5459     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5460     0x0000ffff                                                              /* end                          */
5461     };
5462     static const DWORD vs_1_code[] = {
5463     0xfffe0101,                                                             /* vs_1_1                       */
5464     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5465     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5466     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5467     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5468     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5469     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5470     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5471     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5472     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5473     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5474     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5475     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5476     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5477     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5478     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5479     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5480     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5481     0x0000ffff
5482     };
5483     DWORD vs_2_code[] = {
5484     0xfffe0200,                                                             /* vs_2_0                       */
5485     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5486     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5487     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5488     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5489     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5490     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5491     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5492     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5493     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5494     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5495     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5496     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5497     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5498     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5499     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5500     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5501     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5502     0x0000ffff                                                              /* end                          */
5503     };
5504     /* TODO: Define normal, tangent, blendweight and depth here */
5505     static const DWORD vs_3_code[] = {
5506     0xfffe0300,                                                             /* vs_3_0                       */
5507     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5508     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5509     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5510     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5511     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5512     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5513     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5514     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5515     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5516     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5517     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5518     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5519     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5520     0x0000ffff                                                              /* end                          */
5521     };
5522     float quad1[] =  {
5523         -1.0,   -1.0,   0.1,
5524          0.0,   -1.0,   0.1,
5525         -1.0,    0.0,   0.1,
5526          0.0,    0.0,   0.1
5527     };
5528     float quad2[] =  {
5529          0.0,   -1.0,   0.1,
5530          1.0,   -1.0,   0.1,
5531          0.0,    0.0,   0.1,
5532          1.0,    0.0,   0.1
5533     };
5534     float quad3[] =  {
5535         -1.0,    0.0,   0.1,
5536          0.0,    0.0,   0.1,
5537         -1.0,    1.0,   0.1,
5538          0.0,    1.0,   0.1
5539     };
5540
5541     HRESULT hr;
5542     DWORD color;
5543     IDirect3DPixelShader9 *pixelshader = NULL;
5544     IDirect3DVertexShader9 *vs_1_shader = NULL;
5545     IDirect3DVertexShader9 *vs_2_shader = NULL;
5546     IDirect3DVertexShader9 *vs_3_shader = NULL;
5547
5548     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5549
5550     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5551     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5552     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5553     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5554     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5555     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5556     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5557     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5558     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5559     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5560     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5561
5562     hr = IDirect3DDevice9_BeginScene(device);
5563     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5564     if(SUCCEEDED(hr))
5565     {
5566         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5567         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5568         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5569         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5570
5571         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5572         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5573         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5574         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5575
5576         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5577         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5579         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5580
5581         hr = IDirect3DDevice9_EndScene(device);
5582         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5583     }
5584     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5585     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5586
5587     color = getPixelColor(device, 160, 120);
5588     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5589        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5590     /* Accept two ways of oFog handling:
5591      *
5592      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5593      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5594      *
5595      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5596      *    This happens with software vertex processing and on Intel cards
5597      *
5598      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5599      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5600      */
5601     color = getPixelColor(device, 160, 360);
5602     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5603        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5604        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5605     color = getPixelColor(device, 480, 360);
5606     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5607        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5608        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5609
5610     /* cleanup */
5611     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5612     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5613     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5614     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5615     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5616     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5617     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5618     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5619 }
5620
5621 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5622     static const DWORD vs_code[] = {
5623     0xfffe0300,                                                             /* vs_3_0                       */
5624     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5625     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5626     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5627     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5628     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5629     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5630     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5631     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5632     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5633     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5634     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5635     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5636     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5637
5638     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5639     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5640     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5641     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5642     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5643     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5644     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5645     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5646     0x0000ffff                                                              /* end                          */
5647     };
5648     static const DWORD ps_1_code[] = {
5649     0xffff0104,                                                             /* ps_1_4                       */
5650     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5651     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5652     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5653     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5654     0x0000ffff                                                              /* end                          */
5655     };
5656     static const DWORD ps_2_code[] = {
5657     0xffff0200,                                                             /* ps_2_0                       */
5658     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5659     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5660     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5661
5662     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5663     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5664     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5665     0x0000ffff                                                              /* end                          */
5666     };
5667     static const DWORD ps_3_code[] = {
5668     0xffff0300,                                                             /* ps_3_0                       */
5669     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5670     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5671     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5672
5673     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5674     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5675     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5676     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5677     0x0000ffff                                                              /* end                          */
5678     };
5679
5680     float quad1[] =  {
5681         -1.0,   -1.0,   0.1,
5682          0.0,   -1.0,   0.1,
5683         -1.0,    0.0,   0.1,
5684          0.0,    0.0,   0.1
5685     };
5686     float quad2[] =  {
5687          0.0,   -1.0,   0.1,
5688          1.0,   -1.0,   0.1,
5689          0.0,    0.0,   0.1,
5690          1.0,    0.0,   0.1
5691     };
5692     float quad3[] =  {
5693         -1.0,    0.0,   0.1,
5694          0.0,    0.0,   0.1,
5695         -1.0,    1.0,   0.1,
5696          0.0,    1.0,   0.1
5697     };
5698     float quad4[] =  {
5699          0.0,    0.0,   0.1,
5700          1.0,    0.0,   0.1,
5701          0.0,    1.0,   0.1,
5702          1.0,    1.0,   0.1
5703     };
5704
5705     HRESULT hr;
5706     DWORD color;
5707     IDirect3DVertexShader9 *vertexshader = NULL;
5708     IDirect3DPixelShader9 *ps_1_shader = NULL;
5709     IDirect3DPixelShader9 *ps_2_shader = NULL;
5710     IDirect3DPixelShader9 *ps_3_shader = NULL;
5711     IDirect3DTexture9 *texture = NULL;
5712     D3DLOCKED_RECT lr;
5713     unsigned int x, y;
5714
5715     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5716
5717     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5718     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5719     if(FAILED(hr)) {
5720         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5721         return;
5722     }
5723     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5724     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5725     for(y = 0; y < 512; y++) {
5726         for(x = 0; x < 512; x++) {
5727             double r_f = (double) x / (double) 512;
5728             double g_f = (double) y / (double) 512;
5729             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5730             unsigned short r = (unsigned short) (r_f * 65535.0);
5731             unsigned short g = (unsigned short) (g_f * 65535.0);
5732             dst[0] = r;
5733             dst[1] = g;
5734             dst[2] = 0;
5735             dst[3] = 65535;
5736         }
5737     }
5738     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5739     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5740
5741     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5742     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5743     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5744     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5745     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5746     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5747     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5748     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5749     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5750     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5751     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5752
5753     hr = IDirect3DDevice9_BeginScene(device);
5754     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5755     if(SUCCEEDED(hr))
5756     {
5757         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5758         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5759         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5760         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5761
5762         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5763         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5764         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5765         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5766
5767         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5768         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5769         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5770         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5771
5772         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5773         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5774         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5775         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5776         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5777         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5778         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5779         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5780         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5781         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5782
5783         hr = IDirect3DDevice9_EndScene(device);
5784         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5785     }
5786     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5787     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5788
5789     color = getPixelColor(device, 160, 120);
5790     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5791        (color & 0x0000ff00) == 0x0000ff00 &&
5792        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5793        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5794     color = getPixelColor(device, 160, 360);
5795     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5796        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5797        (color & 0x000000ff) == 0x00000000,
5798        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5799     color = getPixelColor(device, 480, 360);
5800     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5801        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5802        (color & 0x000000ff) == 0x00000000,
5803        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5804     color = getPixelColor(device, 480, 160);
5805     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5806        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5807        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5808        (color & 0x000000ff) == 0x00000000),
5809        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5810
5811     /* cleanup */
5812     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5813     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5814     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5815     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5816     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5817     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5818     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5819     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5820     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5821     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5822     if(texture) IDirect3DTexture9_Release(texture);
5823 }
5824
5825 static void test_compare_instructions(IDirect3DDevice9 *device)
5826 {
5827     DWORD shader_sge_vec_code[] = {
5828         0xfffe0101,                                         /* vs_1_1                   */
5829         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5830         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5831         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5832         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5833         0x0000ffff                                          /* end                      */
5834     };
5835     DWORD shader_slt_vec_code[] = {
5836         0xfffe0101,                                         /* vs_1_1                   */
5837         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5838         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5839         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5840         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5841         0x0000ffff                                          /* end                      */
5842     };
5843     DWORD shader_sge_scalar_code[] = {
5844         0xfffe0101,                                         /* vs_1_1                   */
5845         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5846         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5847         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5848         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5849         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5850         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5851         0x0000ffff                                          /* end                      */
5852     };
5853     DWORD shader_slt_scalar_code[] = {
5854         0xfffe0101,                                         /* vs_1_1                   */
5855         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5856         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5857         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5858         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5859         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5860         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5861         0x0000ffff                                          /* end                      */
5862     };
5863     IDirect3DVertexShader9 *shader_sge_vec;
5864     IDirect3DVertexShader9 *shader_slt_vec;
5865     IDirect3DVertexShader9 *shader_sge_scalar;
5866     IDirect3DVertexShader9 *shader_slt_scalar;
5867     HRESULT hr, color;
5868     float quad1[] =  {
5869         -1.0,   -1.0,   0.1,
5870          0.0,   -1.0,   0.1,
5871         -1.0,    0.0,   0.1,
5872          0.0,    0.0,   0.1
5873     };
5874     float quad2[] =  {
5875          0.0,   -1.0,   0.1,
5876          1.0,   -1.0,   0.1,
5877          0.0,    0.0,   0.1,
5878          1.0,    0.0,   0.1
5879     };
5880     float quad3[] =  {
5881         -1.0,    0.0,   0.1,
5882          0.0,    0.0,   0.1,
5883         -1.0,    1.0,   0.1,
5884          0.0,    1.0,   0.1
5885     };
5886     float quad4[] =  {
5887          0.0,    0.0,   0.1,
5888          1.0,    0.0,   0.1,
5889          0.0,    1.0,   0.1,
5890          1.0,    1.0,   0.1
5891     };
5892     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5893     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5894
5895     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5896
5897     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5899     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5901     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5903     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5904     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5905     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5906     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5907     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5908     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5910     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5911
5912     hr = IDirect3DDevice9_BeginScene(device);
5913     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5914     if(SUCCEEDED(hr))
5915     {
5916         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5919         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5920
5921         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5922         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5924         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5925
5926         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5927         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5929         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5930
5931         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5932         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5933
5934         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5935         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5936         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5937         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5938
5939         hr = IDirect3DDevice9_EndScene(device);
5940         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5941     }
5942
5943     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5944     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5945     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5946     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5947
5948     color = getPixelColor(device, 160, 360);
5949     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5950     color = getPixelColor(device, 480, 360);
5951     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5952     color = getPixelColor(device, 160, 120);
5953     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5954     color = getPixelColor(device, 480, 160);
5955     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5956
5957     IDirect3DVertexShader9_Release(shader_sge_vec);
5958     IDirect3DVertexShader9_Release(shader_slt_vec);
5959     IDirect3DVertexShader9_Release(shader_sge_scalar);
5960     IDirect3DVertexShader9_Release(shader_slt_scalar);
5961 }
5962
5963 static void test_vshader_input(IDirect3DDevice9 *device)
5964 {
5965     DWORD swapped_shader_code_3[] = {
5966         0xfffe0300,                                         /* vs_3_0               */
5967         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
5968         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
5969         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5970         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5971         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5972         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
5973         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5974         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5975         0x0000ffff                                          /* end                  */
5976     };
5977     DWORD swapped_shader_code_1[] = {
5978         0xfffe0101,                                         /* vs_1_1               */
5979         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5980         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5981         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5982         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5983         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5984         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5985         0x0000ffff                                          /* end                  */
5986     };
5987     DWORD swapped_shader_code_2[] = {
5988         0xfffe0200,                                         /* vs_2_0               */
5989         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
5990         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
5991         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
5992         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
5993         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
5994         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
5995         0x0000ffff                                          /* end                  */
5996     };
5997     DWORD texcoord_color_shader_code_3[] = {
5998         0xfffe0300,                                         /* vs_3_0               */
5999         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6000         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6001         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6002         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6003         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6004         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6005         0x0000ffff                                          /* end                  */
6006     };
6007     DWORD texcoord_color_shader_code_2[] = {
6008         0xfffe0200,                                         /* vs_2_0               */
6009         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6010         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6011         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6012         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6013         0x0000ffff                                          /* end                  */
6014     };
6015     DWORD texcoord_color_shader_code_1[] = {
6016         0xfffe0101,                                         /* vs_1_1               */
6017         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6018         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6019         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6020         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6021         0x0000ffff                                          /* end                  */
6022     };
6023     DWORD color_color_shader_code_3[] = {
6024         0xfffe0300,                                         /* vs_3_0               */
6025         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6026         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6027         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6028         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6029         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6030         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6031         0x0000ffff                                          /* end                  */
6032     };
6033     DWORD color_color_shader_code_2[] = {
6034         0xfffe0200,                                         /* vs_2_0               */
6035         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6036         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6037         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6038         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6039         0x0000ffff                                          /* end                  */
6040     };
6041     DWORD color_color_shader_code_1[] = {
6042         0xfffe0101,                                         /* vs_1_1               */
6043         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6044         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6045         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6046         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6047         0x0000ffff                                          /* end                  */
6048     };
6049     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6050     HRESULT hr;
6051     DWORD color;
6052     float quad1[] =  {
6053         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6054          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6055         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6056          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6057     };
6058     float quad2[] =  {
6059          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6060          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6061          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6062          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6063     };
6064     float quad3[] =  {
6065         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6066          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6067         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6068          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6069     };
6070     float quad4[] =  {
6071          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6072          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6073          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6074          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6075     };
6076     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6077         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6078         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6079         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6080         D3DDECL_END()
6081     };
6082     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6083         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6084         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6085         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6086         D3DDECL_END()
6087     };
6088     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6089         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6090         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6091         D3DDECL_END()
6092     };
6093     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6094         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6095         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6096         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6097         D3DDECL_END()
6098     };
6099     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6100         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6101         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6102         D3DDECL_END()
6103     };
6104     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6105         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6106         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6107         D3DDECL_END()
6108     };
6109     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6110         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6111         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6112         D3DDECL_END()
6113     };
6114     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6115         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6116         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6117         D3DDECL_END()
6118     };
6119     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6120     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6121     unsigned int i;
6122     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6123     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6124
6125     struct vertex quad1_color[] =  {
6126        {-1.0,   -1.0,   0.1,    0x00ff8040},
6127        { 0.0,   -1.0,   0.1,    0x00ff8040},
6128        {-1.0,    0.0,   0.1,    0x00ff8040},
6129        { 0.0,    0.0,   0.1,    0x00ff8040}
6130     };
6131     struct vertex quad2_color[] =  {
6132        { 0.0,   -1.0,   0.1,    0x00ff8040},
6133        { 1.0,   -1.0,   0.1,    0x00ff8040},
6134        { 0.0,    0.0,   0.1,    0x00ff8040},
6135        { 1.0,    0.0,   0.1,    0x00ff8040}
6136     };
6137     struct vertex quad3_color[] =  {
6138        {-1.0,    0.0,   0.1,    0x00ff8040},
6139        { 0.0,    0.0,   0.1,    0x00ff8040},
6140        {-1.0,    1.0,   0.1,    0x00ff8040},
6141        { 0.0,    1.0,   0.1,    0x00ff8040}
6142     };
6143     float quad4_color[] =  {
6144          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6145          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6146          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6147          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6148     };
6149
6150     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6151     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6152     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6153     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6154     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6155     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6156     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6157     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6158
6159     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6160     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6161     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6162     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6163     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6164     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6165     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6166     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6167
6168     for(i = 1; i <= 3; i++) {
6169         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6170         if(i == 3) {
6171             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6172             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6173         } else if(i == 2){
6174             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6175             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6176         } else if(i == 1) {
6177             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6178             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6179         }
6180
6181         hr = IDirect3DDevice9_BeginScene(device);
6182         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6183         if(SUCCEEDED(hr))
6184         {
6185             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6186             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6187
6188             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6189             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6190             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6191             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6192
6193             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6194             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6195             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6196             if(i == 3 || i == 2) {
6197                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6198             } else if(i == 1) {
6199                 /* Succeeds or fails, depending on SW or HW vertex processing */
6200                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6201             }
6202
6203             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6204             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6205             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6206             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6207
6208             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6209             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6210             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6211             if(i == 3 || i == 2) {
6212                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6213             } else if(i == 1) {
6214                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6215             }
6216
6217             hr = IDirect3DDevice9_EndScene(device);
6218             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6219         }
6220
6221         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6222         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6223
6224         if(i == 3 || i == 2) {
6225             color = getPixelColor(device, 160, 360);
6226             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6227                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6228
6229             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6230             color = getPixelColor(device, 480, 360);
6231             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6232                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6233             color = getPixelColor(device, 160, 120);
6234             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6235             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6236                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6237
6238             color = getPixelColor(device, 480, 160);
6239             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6240         } else if(i == 1) {
6241             color = getPixelColor(device, 160, 360);
6242             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6243                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6244             color = getPixelColor(device, 480, 360);
6245             /* Accept the clear color as well in this case, since SW VP returns an error */
6246             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6247             color = getPixelColor(device, 160, 120);
6248             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6249                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6250             color = getPixelColor(device, 480, 160);
6251             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6252         }
6253
6254         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6255         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6256
6257         /* Now find out if the whole streams are re-read, or just the last active value for the
6258          * vertices is used.
6259          */
6260         hr = IDirect3DDevice9_BeginScene(device);
6261         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6262         if(SUCCEEDED(hr))
6263         {
6264             float quad1_modified[] =  {
6265                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6266                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6267                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6268                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6269             };
6270             float quad2_modified[] =  {
6271                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6272                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6273                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6274                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6275             };
6276
6277             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6278             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6279
6280             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6281             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6282             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6283             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6284
6285             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6286             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6287             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6288             if(i == 3 || i == 2) {
6289                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6290             } else if(i == 1) {
6291                 /* Succeeds or fails, depending on SW or HW vertex processing */
6292                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6293             }
6294
6295             hr = IDirect3DDevice9_EndScene(device);
6296             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6297         }
6298         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6299         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6300
6301         color = getPixelColor(device, 480, 350);
6302         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6303          * as well.
6304          *
6305          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6306          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6307          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6308          * refrast's result.
6309          *
6310          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6311          */
6312         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6313            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6314         color = getPixelColor(device, 160, 120);
6315
6316         IDirect3DDevice9_SetVertexShader(device, NULL);
6317         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6318
6319         IDirect3DVertexShader9_Release(swapped_shader);
6320     }
6321
6322     for(i = 1; i <= 3; i++) {
6323         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6324         if(i == 3) {
6325             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6326             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6327             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6328             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6329         } else if(i == 2){
6330             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6331             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6332             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6333             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6334         } else if(i == 1) {
6335             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6336             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6337             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6338             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6339         }
6340
6341         hr = IDirect3DDevice9_BeginScene(device);
6342         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6343         if(SUCCEEDED(hr))
6344         {
6345             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6346             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6347             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6348             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6349             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6350             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6351
6352             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6353             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6354
6355             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6356             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6357             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6358             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6359             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6360             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6361
6362             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6363             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6364             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6365             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6366             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6367             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6368
6369             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6370             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6371             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6372             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6373
6374             hr = IDirect3DDevice9_EndScene(device);
6375             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6376         }
6377         IDirect3DDevice9_SetVertexShader(device, NULL);
6378         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6379
6380         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6381         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6382
6383         color = getPixelColor(device, 160, 360);
6384         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6385            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6386         color = getPixelColor(device, 480, 360);
6387         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6388            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6389         color = getPixelColor(device, 160, 120);
6390         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6391            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6392         color = getPixelColor(device, 480, 160);
6393         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6394            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6395
6396         IDirect3DVertexShader9_Release(texcoord_color_shader);
6397         IDirect3DVertexShader9_Release(color_color_shader);
6398     }
6399
6400     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6401     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6402     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6403     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6404
6405     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6406     IDirect3DVertexDeclaration9_Release(decl_color_color);
6407     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6408     IDirect3DVertexDeclaration9_Release(decl_color_float);
6409 }
6410
6411 static void srgbtexture_test(IDirect3DDevice9 *device)
6412 {
6413     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6414      * texture stage state to render a quad using that texture.  The resulting
6415      * color components should be 0x36 (~ 0.21), per this formula:
6416      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6417      * This is true where srgb_color > 0.04045.
6418      */
6419     IDirect3D9 *d3d = NULL;
6420     HRESULT hr;
6421     LPDIRECT3DTEXTURE9 texture = NULL;
6422     LPDIRECT3DSURFACE9 surface = NULL;
6423     D3DLOCKED_RECT lr;
6424     DWORD color;
6425     float quad[] = {
6426         -1.0,       1.0,       0.0,     0.0,    0.0,
6427          1.0,       1.0,       0.0,     1.0,    0.0,
6428         -1.0,      -1.0,       0.0,     0.0,    1.0,
6429          1.0,      -1.0,       0.0,     1.0,    1.0,
6430     };
6431
6432
6433     memset(&lr, 0, sizeof(lr));
6434     IDirect3DDevice9_GetDirect3D(device, &d3d);
6435     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6436                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6437                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6438         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6439         goto out;
6440     }
6441
6442     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6443                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6444                                         &texture, NULL);
6445     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6446     if(!texture) {
6447         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6448         goto out;
6449     }
6450     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6451     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6452
6453     fill_surface(surface, 0xff7f7f7f);
6454     IDirect3DSurface9_Release(surface);
6455
6456     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6457     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6458     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6459     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6460
6461     hr = IDirect3DDevice9_BeginScene(device);
6462     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6463     if(SUCCEEDED(hr))
6464     {
6465         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6466         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6467
6468         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6469         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6470
6471
6472         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6473         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6474
6475         hr = IDirect3DDevice9_EndScene(device);
6476         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6477     }
6478
6479     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6480     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6481     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6482     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6483
6484     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6485     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6486
6487     color = getPixelColor(device, 320, 240);
6488     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6489
6490 out:
6491     if(texture) IDirect3DTexture9_Release(texture);
6492     IDirect3D9_Release(d3d);
6493 }
6494
6495 static void shademode_test(IDirect3DDevice9 *device)
6496 {
6497     /* Render a quad and try all of the different fixed function shading models. */
6498     HRESULT hr;
6499     DWORD color0, color1;
6500     DWORD color0_gouraud = 0, color1_gouraud = 0;
6501     DWORD shademode = D3DSHADE_FLAT;
6502     DWORD primtype = D3DPT_TRIANGLESTRIP;
6503     LPVOID data = NULL;
6504     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6505     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6506     UINT i, j;
6507     struct vertex quad_strip[] =
6508     {
6509         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6510         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6511         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6512         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6513     };
6514     struct vertex quad_list[] =
6515     {
6516         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6517         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6518         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6519
6520         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6521         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6522         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6523     };
6524
6525     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6526                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6527     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6528     if (FAILED(hr)) goto bail;
6529
6530     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6531                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6532     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6533     if (FAILED(hr)) goto bail;
6534
6535     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6536     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6537
6538     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6539     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6540
6541     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6542     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6543     memcpy(data, quad_strip, sizeof(quad_strip));
6544     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6545     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6546
6547     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6548     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6549     memcpy(data, quad_list, sizeof(quad_list));
6550     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6551     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6552
6553     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6554      * the color fixups we have to do for FLAT shading will be dependent on that. */
6555     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6556     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6557
6558     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6559     for (j=0; j<2; j++) {
6560
6561         /* Inner loop just changes the D3DRS_SHADEMODE */
6562         for (i=0; i<3; i++) {
6563             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6564             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6565
6566             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6567             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6568
6569             hr = IDirect3DDevice9_BeginScene(device);
6570             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6571             if(SUCCEEDED(hr))
6572             {
6573                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6574                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6575
6576                 hr = IDirect3DDevice9_EndScene(device);
6577                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6578             }
6579
6580             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6581             ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6582
6583             /* Sample two spots from the output */
6584             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6585             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6586             switch(shademode) {
6587                 case D3DSHADE_FLAT:
6588                     /* Should take the color of the first vertex of each triangle */
6589                     todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6590                     todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6591                     shademode = D3DSHADE_GOURAUD;
6592                     break;
6593                 case D3DSHADE_GOURAUD:
6594                     /* Should be an interpolated blend */
6595
6596                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6597                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6598                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6599                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6600
6601                     color0_gouraud = color0;
6602                     color1_gouraud = color1;
6603
6604                     shademode = D3DSHADE_PHONG;
6605                     break;
6606                 case D3DSHADE_PHONG:
6607                     /* Should be the same as GOURAUD, since no hardware implements this */
6608                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6609                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6610                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6611                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6612
6613                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6614                             color0_gouraud, color0);
6615                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6616                             color1_gouraud, color1);
6617                     break;
6618             }
6619         }
6620         /* Now, do it all over again with a TRIANGLELIST */
6621         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6622         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6623         primtype = D3DPT_TRIANGLELIST;
6624         shademode = D3DSHADE_FLAT;
6625     }
6626
6627 bail:
6628     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6629     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6630     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6631     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6632
6633     if (vb_strip)
6634         IDirect3DVertexBuffer9_Release(vb_strip);
6635     if (vb_list)
6636         IDirect3DVertexBuffer9_Release(vb_list);
6637 }
6638
6639
6640 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6641 {
6642     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6643      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6644      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6645      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6646      * 0.73
6647      *
6648      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6649      * so use shaders for this task
6650      */
6651     IDirect3DPixelShader9 *pshader;
6652     IDirect3DVertexShader9 *vshader;
6653     IDirect3D9 *d3d;
6654     DWORD vshader_code[] = {
6655         0xfffe0101,                                                             /* vs_1_1                       */
6656         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6657         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6658         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6659         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6660         0x0000ffff                                                              /* end                          */
6661     };
6662     DWORD pshader_code[] = {
6663         0xffff0101,                                                             /* ps_1_1                       */
6664         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6665         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6666         0x0000ffff                                                              /* end                          */
6667     };
6668     const float quad[] = {
6669        -1.0,   -1.0,    0.1,
6670         1.0,   -1.0,    0.1,
6671        -1.0,    1.0,    0.1,
6672         1.0,    1.0,    0.1
6673     };
6674     HRESULT hr;
6675     D3DCOLOR color;
6676
6677     IDirect3DDevice9_GetDirect3D(device, &d3d);
6678     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6679      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6680      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6681      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6682      * works
6683      */
6684     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6685                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6686                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6687         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6688         IDirect3D9_Release(d3d);
6689         return;
6690     }
6691     IDirect3D9_Release(d3d);
6692
6693     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6694     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6695
6696     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6697     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6698     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6699     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6701     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6702     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6703     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6704     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6705     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6706
6707     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6708     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6709     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6710     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6711     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6712     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6713     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6714     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6715     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6716     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6717
6718     hr = IDirect3DDevice9_BeginScene(device);
6719     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6720     if(SUCCEEDED(hr)) {
6721         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6722         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6723
6724         hr = IDirect3DDevice9_EndScene(device);
6725         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6726     }
6727
6728     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6729     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6730     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6731     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6732     IDirect3DPixelShader9_Release(pshader);
6733     IDirect3DVertexShader9_Release(vshader);
6734
6735     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6736     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6737     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6738     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6739
6740     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6741     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6742     color = getPixelColor(device, 160, 360);
6743     ok(color_match(color, 0x00808080, 1),
6744             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6745 }
6746
6747 static void alpha_test(IDirect3DDevice9 *device)
6748 {
6749     HRESULT hr;
6750     IDirect3DTexture9 *offscreenTexture;
6751     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6752     DWORD color;
6753
6754     struct vertex quad1[] =
6755     {
6756         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6757         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6758         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6759         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6760     };
6761     struct vertex quad2[] =
6762     {
6763         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6764         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6765         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6766         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6767     };
6768     static const float composite_quad[][5] = {
6769         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6770         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6771         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6772         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6773     };
6774
6775     /* Clear the render target with alpha = 0.5 */
6776     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6777     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6778
6779     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6780     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6781
6782     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6783     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6784     if(!backbuffer) {
6785         goto out;
6786     }
6787
6788     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6789     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6790     if(!offscreen) {
6791         goto out;
6792     }
6793
6794     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6795     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6796
6797     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6798     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6799     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6800     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6801     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6802     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6803     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6804     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6805     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6806     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6807
6808     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6809     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6810     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6811
6812         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6813         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6814         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6815         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6816         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6818         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6819
6820         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6821         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6822         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6823         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6824         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6825         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6826
6827         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6828          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6829          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6830         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6831         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6832         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6833         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6834
6835         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6836         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6837         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6838         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6839         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6840         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6841
6842         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6843         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6844         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6845         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6846         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6847         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6848
6849         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6850         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6851
6852         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6853          * Disable alpha blending for the final composition
6854          */
6855         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6856         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6857         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6858         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6859
6860         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6861         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6862         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6863         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6864         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6865         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6866
6867         hr = IDirect3DDevice9_EndScene(device);
6868         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6869     }
6870
6871     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6872
6873     color = getPixelColor(device, 160, 360);
6874     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6875        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6876
6877     color = getPixelColor(device, 160, 120);
6878     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6879        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6880
6881     color = getPixelColor(device, 480, 360);
6882     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6883        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6884
6885     color = getPixelColor(device, 480, 120);
6886     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6887        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6888
6889     out:
6890     /* restore things */
6891     if(backbuffer) {
6892         IDirect3DSurface9_Release(backbuffer);
6893     }
6894     if(offscreenTexture) {
6895         IDirect3DTexture9_Release(offscreenTexture);
6896     }
6897     if(offscreen) {
6898         IDirect3DSurface9_Release(offscreen);
6899     }
6900 }
6901
6902 struct vertex_shortcolor {
6903     float x, y, z;
6904     unsigned short r, g, b, a;
6905 };
6906 struct vertex_floatcolor {
6907     float x, y, z;
6908     float r, g, b, a;
6909 };
6910
6911 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6912 {
6913     HRESULT hr;
6914     BOOL s_ok, ub_ok, f_ok;
6915     DWORD color, size, i;
6916     void *data;
6917     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6918         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6919         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6920         D3DDECL_END()
6921     };
6922     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6923         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6924         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6925         D3DDECL_END()
6926     };
6927     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6928         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6929         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6930         D3DDECL_END()
6931     };
6932     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6933         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6934         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6935         D3DDECL_END()
6936     };
6937     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6938         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6939         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6940         D3DDECL_END()
6941     };
6942     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6943         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6944         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6945         D3DDECL_END()
6946     };
6947     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6948         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6949         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6950         D3DDECL_END()
6951     };
6952     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6953     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6954     IDirect3DVertexBuffer9 *vb, *vb2;
6955     struct vertex quad1[] =                             /* D3DCOLOR */
6956     {
6957         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6958         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6959         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6960         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6961     };
6962     struct vertex quad2[] =                             /* UBYTE4N */
6963     {
6964         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6965         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6966         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6967         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6968     };
6969     struct vertex_shortcolor quad3[] =                  /* short */
6970     {
6971         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6972         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6973         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6974         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6975     };
6976     struct vertex_floatcolor quad4[] =
6977     {
6978         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6979         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6980         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6981         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6982     };
6983     DWORD colors[] = {
6984         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
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     };
7001     float quads[] = {
7002         -1.0,   -1.0,     0.1,
7003         -1.0,    0.0,     0.1,
7004          0.0,   -1.0,     0.1,
7005          0.0,    0.0,     0.1,
7006
7007          0.0,   -1.0,     0.1,
7008          0.0,    0.0,     0.1,
7009          1.0,   -1.0,     0.1,
7010          1.0,    0.0,     0.1,
7011
7012          0.0,    0.0,     0.1,
7013          0.0,    1.0,     0.1,
7014          1.0,    0.0,     0.1,
7015          1.0,    1.0,     0.1,
7016
7017         -1.0,    0.0,     0.1,
7018         -1.0,    1.0,     0.1,
7019          0.0,    0.0,     0.1,
7020          0.0,    1.0,     0.1
7021     };
7022     struct tvertex quad_transformed[] = {
7023        {  90,    110,     0.1,      2.0,        0x00ffff00},
7024        { 570,    110,     0.1,      2.0,        0x00ffff00},
7025        {  90,    300,     0.1,      2.0,        0x00ffff00},
7026        { 570,    300,     0.1,      2.0,        0x00ffff00}
7027     };
7028     D3DCAPS9 caps;
7029
7030     memset(&caps, 0, sizeof(caps));
7031     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7032     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7033
7034     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7035     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7036
7037     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7038     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7039     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7040     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7041     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7042     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7043     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7044         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7045         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7046         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7047         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7048     } else {
7049         trace("D3DDTCAPS_UBYTE4N not supported\n");
7050         dcl_ubyte_2 = NULL;
7051         dcl_ubyte = NULL;
7052     }
7053     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7054     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7055     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7056     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7057
7058     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7059     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7060                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7061     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7062
7063     hr = IDirect3DDevice9_BeginScene(device);
7064     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7065     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7066     if(SUCCEEDED(hr)) {
7067         if(dcl_color) {
7068             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7069             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7070             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7071             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7072         }
7073
7074         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7075          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7076          * using software vertex processing. Doh!
7077          */
7078         if(dcl_ubyte) {
7079             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7080             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7081             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7082             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7083             ub_ok = SUCCEEDED(hr);
7084         }
7085
7086         if(dcl_short) {
7087             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7088             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7089             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7090             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7091             s_ok = SUCCEEDED(hr);
7092         }
7093
7094         if(dcl_float) {
7095             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7096             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7097             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7098             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7099             f_ok = SUCCEEDED(hr);
7100         }
7101
7102         hr = IDirect3DDevice9_EndScene(device);
7103         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7104     }
7105
7106     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7107     if(dcl_short) {
7108         color = getPixelColor(device, 480, 360);
7109         ok(color == 0x000000ff || !s_ok,
7110            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7111     }
7112     if(dcl_ubyte) {
7113         color = getPixelColor(device, 160, 120);
7114         ok(color == 0x0000ffff || !ub_ok,
7115            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7116     }
7117     if(dcl_color) {
7118         color = getPixelColor(device, 160, 360);
7119         ok(color == 0x00ffff00,
7120            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7121     }
7122     if(dcl_float) {
7123         color = getPixelColor(device, 480, 120);
7124         ok(color == 0x00ff0000 || !f_ok,
7125            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7126     }
7127
7128     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7129      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7130      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7131      * whether the immediate mode code works
7132      */
7133     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7134     hr = IDirect3DDevice9_BeginScene(device);
7135     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7136     if(SUCCEEDED(hr)) {
7137         if(dcl_color) {
7138             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7139             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7140             memcpy(data, quad1, sizeof(quad1));
7141             hr = IDirect3DVertexBuffer9_Unlock(vb);
7142             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7143             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7144             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7145             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7146             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7147             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7148             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7149         }
7150
7151         if(dcl_ubyte) {
7152             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7153             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7154             memcpy(data, quad2, sizeof(quad2));
7155             hr = IDirect3DVertexBuffer9_Unlock(vb);
7156             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7157             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7158             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7159             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7160             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7161             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7162             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7163                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7164             ub_ok = SUCCEEDED(hr);
7165         }
7166
7167         if(dcl_short) {
7168             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7169             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7170             memcpy(data, quad3, sizeof(quad3));
7171             hr = IDirect3DVertexBuffer9_Unlock(vb);
7172             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7173             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7174             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7175             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7176             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7177             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7178             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7179                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7180             s_ok = SUCCEEDED(hr);
7181         }
7182
7183         if(dcl_float) {
7184             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7185             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7186             memcpy(data, quad4, sizeof(quad4));
7187             hr = IDirect3DVertexBuffer9_Unlock(vb);
7188             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7189             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7190             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7191             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7192             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7193             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7194             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7195                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7196             f_ok = SUCCEEDED(hr);
7197         }
7198
7199         hr = IDirect3DDevice9_EndScene(device);
7200         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7201     }
7202
7203     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7204     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7205     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7206     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7207
7208     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7209     if(dcl_short) {
7210         color = getPixelColor(device, 480, 360);
7211         ok(color == 0x000000ff || !s_ok,
7212            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7213     }
7214     if(dcl_ubyte) {
7215         color = getPixelColor(device, 160, 120);
7216         ok(color == 0x0000ffff || !ub_ok,
7217            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7218     }
7219     if(dcl_color) {
7220         color = getPixelColor(device, 160, 360);
7221         ok(color == 0x00ffff00,
7222            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7223     }
7224     if(dcl_float) {
7225         color = getPixelColor(device, 480, 120);
7226         ok(color == 0x00ff0000 || !f_ok,
7227            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7228     }
7229
7230     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7231     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7232
7233     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7234     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7235     memcpy(data, quad_transformed, sizeof(quad_transformed));
7236     hr = IDirect3DVertexBuffer9_Unlock(vb);
7237     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7238
7239     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7240     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7241
7242     hr = IDirect3DDevice9_BeginScene(device);
7243     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7244     if(SUCCEEDED(hr)) {
7245         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7246         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7247         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7248         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7249
7250         hr = IDirect3DDevice9_EndScene(device);
7251         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7252     }
7253
7254     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7255     color = getPixelColor(device, 88, 108);
7256     ok(color == 0x000000ff,
7257        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7258     color = getPixelColor(device, 92, 108);
7259     ok(color == 0x000000ff,
7260        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7261     color = getPixelColor(device, 88, 112);
7262     ok(color == 0x000000ff,
7263        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7264     color = getPixelColor(device, 92, 112);
7265     ok(color == 0x00ffff00,
7266        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7267
7268     color = getPixelColor(device, 568, 108);
7269     ok(color == 0x000000ff,
7270        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7271     color = getPixelColor(device, 572, 108);
7272     ok(color == 0x000000ff,
7273        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7274     color = getPixelColor(device, 568, 112);
7275     ok(color == 0x00ffff00,
7276        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7277     color = getPixelColor(device, 572, 112);
7278     ok(color == 0x000000ff,
7279        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7280
7281     color = getPixelColor(device, 88, 298);
7282     ok(color == 0x000000ff,
7283        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7284     color = getPixelColor(device, 92, 298);
7285     ok(color == 0x00ffff00,
7286        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7287     color = getPixelColor(device, 88, 302);
7288     ok(color == 0x000000ff,
7289        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7290     color = getPixelColor(device, 92, 302);
7291     ok(color == 0x000000ff,
7292        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7293
7294     color = getPixelColor(device, 568, 298);
7295     ok(color == 0x00ffff00,
7296        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7297     color = getPixelColor(device, 572, 298);
7298     ok(color == 0x000000ff,
7299        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7300     color = getPixelColor(device, 568, 302);
7301     ok(color == 0x000000ff,
7302        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7303     color = getPixelColor(device, 572, 302);
7304     ok(color == 0x000000ff,
7305        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7306
7307     /* This test is pointless without those two declarations: */
7308     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7309         skip("color-ubyte switching test declarations aren't supported\n");
7310         goto out;
7311     }
7312
7313     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7314     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7315     memcpy(data, quads, sizeof(quads));
7316     hr = IDirect3DVertexBuffer9_Unlock(vb);
7317     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7318     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7319                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7320     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7321     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7322     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7323     memcpy(data, colors, sizeof(colors));
7324     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7325     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7326
7327     for(i = 0; i < 2; i++) {
7328         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7329         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7330
7331         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7332         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7333         if(i == 0) {
7334             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7335         } else {
7336             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7337         }
7338         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7339
7340         hr = IDirect3DDevice9_BeginScene(device);
7341         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7342         ub_ok = FALSE;
7343         if(SUCCEEDED(hr)) {
7344             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7345             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7346             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7347             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7348                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7349             ub_ok = SUCCEEDED(hr);
7350
7351             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7352             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7353             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7354             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7355
7356             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7357             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7358             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7359             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7360                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7361             ub_ok = (SUCCEEDED(hr) && ub_ok);
7362
7363             hr = IDirect3DDevice9_EndScene(device);
7364             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7365         }
7366
7367         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7368         if(i == 0) {
7369             color = getPixelColor(device, 480, 360);
7370             ok(color == 0x00ff0000,
7371                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7372             color = getPixelColor(device, 160, 120);
7373             ok(color == 0x00ffffff,
7374                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7375             color = getPixelColor(device, 160, 360);
7376             ok(color == 0x000000ff || !ub_ok,
7377                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7378             color = getPixelColor(device, 480, 120);
7379             ok(color == 0x000000ff || !ub_ok,
7380                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7381         } else {
7382             color = getPixelColor(device, 480, 360);
7383             ok(color == 0x000000ff,
7384                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7385             color = getPixelColor(device, 160, 120);
7386             ok(color == 0x00ffffff,
7387                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7388             color = getPixelColor(device, 160, 360);
7389             ok(color == 0x00ff0000 || !ub_ok,
7390                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7391             color = getPixelColor(device, 480, 120);
7392             ok(color == 0x00ff0000 || !ub_ok,
7393                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7394         }
7395     }
7396
7397     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7398     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7399     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7400     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7401     IDirect3DVertexBuffer9_Release(vb2);
7402
7403     out:
7404     IDirect3DVertexBuffer9_Release(vb);
7405     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7406     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7407     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7408     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7409     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7410     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7411     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7412 }
7413
7414 struct vertex_float16color {
7415     float x, y, z;
7416     DWORD c1, c2;
7417 };
7418
7419 static void test_vshader_float16(IDirect3DDevice9 *device)
7420 {
7421     HRESULT hr;
7422     DWORD color;
7423     void *data;
7424     static const D3DVERTEXELEMENT9 decl_elements[] = {
7425         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7426         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7427         D3DDECL_END()
7428     };
7429     IDirect3DVertexDeclaration9 *vdecl = NULL;
7430     IDirect3DVertexBuffer9 *buffer = NULL;
7431     IDirect3DVertexShader9 *shader;
7432     DWORD shader_code[] = {
7433         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7434         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7435         0x90e40001, 0x0000ffff
7436     };
7437     struct vertex_float16color quad[] = {
7438         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7439         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7440         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7441         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7442
7443         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7444         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7445         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7446         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7447
7448         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7449         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7450         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7451         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7452
7453         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7454         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7455         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7456         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7457     };
7458
7459     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7460     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7461
7462     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7463     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7464     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7465     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7466     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7467     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7468
7469     hr = IDirect3DDevice9_BeginScene(device);
7470     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7471     if(SUCCEEDED(hr)) {
7472         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7473         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7474         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7475         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7476         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7477         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7478         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7479         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7480         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7481         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7482
7483         hr = IDirect3DDevice9_EndScene(device);
7484         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7485     }
7486     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7487     color = getPixelColor(device, 480, 360);
7488     ok(color == 0x00ff0000,
7489        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7490     color = getPixelColor(device, 160, 120);
7491     ok(color == 0x00000000,
7492        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7493     color = getPixelColor(device, 160, 360);
7494     ok(color == 0x0000ff00,
7495        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7496     color = getPixelColor(device, 480, 120);
7497     ok(color == 0x000000ff,
7498        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7499
7500     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7502
7503     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7504                                              D3DPOOL_MANAGED, &buffer, NULL);
7505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7506     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7507     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7508     memcpy(data, quad, sizeof(quad));
7509     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7510     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7511     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7512     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7513
7514     hr = IDirect3DDevice9_BeginScene(device);
7515     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7516     if(SUCCEEDED(hr)) {
7517             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7518             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7519             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7520             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7521             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7522             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7523             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7524             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7525
7526             hr = IDirect3DDevice9_EndScene(device);
7527             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7528     }
7529
7530     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7531     color = getPixelColor(device, 480, 360);
7532     ok(color == 0x00ff0000,
7533        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7534     color = getPixelColor(device, 160, 120);
7535     ok(color == 0x00000000,
7536        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7537     color = getPixelColor(device, 160, 360);
7538     ok(color == 0x0000ff00,
7539        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7540     color = getPixelColor(device, 480, 120);
7541     ok(color == 0x000000ff,
7542        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7543
7544     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7545     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7546     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7547     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7548     IDirect3DDevice9_SetVertexShader(device, NULL);
7549     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7550
7551     IDirect3DVertexDeclaration9_Release(vdecl);
7552     IDirect3DVertexShader9_Release(shader);
7553     IDirect3DVertexBuffer9_Release(buffer);
7554 }
7555
7556 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7557 {
7558     D3DCAPS9 caps;
7559     IDirect3DTexture9 *texture;
7560     HRESULT hr;
7561     D3DLOCKED_RECT rect;
7562     unsigned int x, y;
7563     DWORD *dst, color;
7564     const float quad[] = {
7565         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7566          1.0,   -1.0,   0.1,    1.2,   -0.2,
7567         -1.0,    1.0,   0.1,   -0.2,    1.2,
7568          1.0,    1.0,   0.1,    1.2,    1.2
7569     };
7570     memset(&caps, 0, sizeof(caps));
7571
7572     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7573     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7574     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7575         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7576         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7577            "Card has conditional NP2 support without power of two restriction set\n");
7578         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7579         return;
7580     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7581         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7582         return;
7583     }
7584
7585     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7586     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7587
7588     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7589     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7590
7591     memset(&rect, 0, sizeof(rect));
7592     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7593     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7594     for(y = 0; y < 10; y++) {
7595         for(x = 0; x < 10; x++) {
7596             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7597             if(x == 0 || x == 9 || y == 0 || y == 9) {
7598                 *dst = 0x00ff0000;
7599             } else {
7600                 *dst = 0x000000ff;
7601             }
7602         }
7603     }
7604     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7605     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7606
7607     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7608     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7609     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7610     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7611     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7612     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7613     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7614     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7615
7616     hr = IDirect3DDevice9_BeginScene(device);
7617     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7618     if(SUCCEEDED(hr)) {
7619         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7620         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7621
7622         hr = IDirect3DDevice9_EndScene(device);
7623         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7624     }
7625
7626     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7627
7628     color = getPixelColor(device,    1,  1);
7629     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7630     color = getPixelColor(device, 639, 479);
7631     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7632
7633     color = getPixelColor(device, 135, 101);
7634     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7635     color = getPixelColor(device, 140, 101);
7636     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7637     color = getPixelColor(device, 135, 105);
7638     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7639     color = getPixelColor(device, 140, 105);
7640     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7641
7642     color = getPixelColor(device, 135, 376);
7643     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7644     color = getPixelColor(device, 140, 376);
7645     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7646     color = getPixelColor(device, 135, 379);
7647     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7648     color = getPixelColor(device, 140, 379);
7649     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7650
7651     color = getPixelColor(device, 500, 101);
7652     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7653     color = getPixelColor(device, 504, 101);
7654     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7655     color = getPixelColor(device, 500, 105);
7656     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7657     color = getPixelColor(device, 504, 105);
7658     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7659
7660     color = getPixelColor(device, 500, 376);
7661     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7662     color = getPixelColor(device, 504, 376);
7663     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7664     color = getPixelColor(device, 500, 380);
7665     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7666     color = getPixelColor(device, 504, 380);
7667     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7668
7669     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7670     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7671     IDirect3DTexture9_Release(texture);
7672 }
7673
7674 static void vFace_register_test(IDirect3DDevice9 *device)
7675 {
7676     HRESULT hr;
7677     DWORD color;
7678     const DWORD shader_code[] = {
7679         0xffff0300,                                                             /* ps_3_0                     */
7680         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7681         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7682         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7683         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7684         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7685         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7686         0x0000ffff                                                              /* END                        */
7687     };
7688     IDirect3DPixelShader9 *shader;
7689     IDirect3DTexture9 *texture;
7690     IDirect3DSurface9 *surface, *backbuffer;
7691     const float quad[] = {
7692         -1.0,   -1.0,   0.1,
7693          1.0,   -1.0,   0.1,
7694         -1.0,    0.0,   0.1,
7695
7696          1.0,   -1.0,   0.1,
7697          1.0,    0.0,   0.1,
7698         -1.0,    0.0,   0.1,
7699
7700         -1.0,    0.0,   0.1,
7701         -1.0,    1.0,   0.1,
7702          1.0,    0.0,   0.1,
7703
7704          1.0,    0.0,   0.1,
7705         -1.0,    1.0,   0.1,
7706          1.0,    1.0,   0.1,
7707     };
7708     const float blit[] = {
7709          0.0,   -1.0,   0.1,    0.0,    0.0,
7710          1.0,   -1.0,   0.1,    1.0,    0.0,
7711          0.0,    1.0,   0.1,    0.0,    1.0,
7712          1.0,    1.0,   0.1,    1.0,    1.0,
7713     };
7714
7715     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7716     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7717     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7718     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7719     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7720     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7721     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7722     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7723     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7724     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7725     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7726     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7727
7728     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7729     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7730
7731     hr = IDirect3DDevice9_BeginScene(device);
7732     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7733     if(SUCCEEDED(hr)) {
7734         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7735         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7736         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7737         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7738         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7739         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7740         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7741         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7742         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7743         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7744         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7745
7746         /* Blit the texture onto the back buffer to make it visible */
7747         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7748         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7749         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7750         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7751         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7752         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7753         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7754         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7755         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7756         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7757
7758         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7759         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7760
7761         hr = IDirect3DDevice9_EndScene(device);
7762         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7763     }
7764
7765     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7766     color = getPixelColor(device, 160, 360);
7767     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7768     color = getPixelColor(device, 160, 120);
7769     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7770     color = getPixelColor(device, 480, 360);
7771     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7772     color = getPixelColor(device, 480, 120);
7773     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7774
7775     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7776     IDirect3DDevice9_SetTexture(device, 0, NULL);
7777     IDirect3DPixelShader9_Release(shader);
7778     IDirect3DSurface9_Release(surface);
7779     IDirect3DSurface9_Release(backbuffer);
7780     IDirect3DTexture9_Release(texture);
7781 }
7782
7783 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7784 {
7785     HRESULT hr;
7786     DWORD color;
7787     int i;
7788     D3DCAPS9 caps;
7789     BOOL L6V5U5_supported = FALSE;
7790     IDirect3DTexture9 *tex1, *tex2;
7791     D3DLOCKED_RECT locked_rect;
7792
7793     static const float quad[][7] = {
7794         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7795         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7796         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7797         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7798     };
7799
7800     static const D3DVERTEXELEMENT9 decl_elements[] = {
7801         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7802         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7803         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7804         D3DDECL_END()
7805     };
7806
7807     /* use asymmetric matrix to test loading */
7808     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7809     float scale, offset;
7810
7811     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7812     IDirect3DTexture9           *texture            = NULL;
7813
7814     memset(&caps, 0, sizeof(caps));
7815     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7816     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7817     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7818         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7819         return;
7820     } else {
7821         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7822          * They report that it is not supported, but after that bump mapping works properly. So just test
7823          * if the format is generally supported, and check the BUMPENVMAP flag
7824          */
7825         IDirect3D9 *d3d9;
7826
7827         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7828         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7829                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7830         L6V5U5_supported = SUCCEEDED(hr);
7831         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7832                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7833         IDirect3D9_Release(d3d9);
7834         if(FAILED(hr)) {
7835             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7836             return;
7837         }
7838     }
7839
7840     /* Generate the textures */
7841     generate_bumpmap_textures(device);
7842
7843     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7844     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7845     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7847     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7848     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7849     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7850     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7851
7852     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7853     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7854     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7855     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7856     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7857     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7858
7859     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7860     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7861     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7862     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7863     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7864     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7865
7866     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7867     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7868
7869     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7870     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7871
7872     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7873     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7874
7875
7876     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7877     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7878     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7879     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7880
7881     hr = IDirect3DDevice9_BeginScene(device);
7882     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7883
7884     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7885     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7886
7887     hr = IDirect3DDevice9_EndScene(device);
7888     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7889
7890     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7891     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7892
7893     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7894      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7895      * But since testing the color match is not the purpose of the test don't be too picky
7896      */
7897     color = getPixelColor(device, 320-32, 240);
7898     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7899     color = getPixelColor(device, 320+32, 240);
7900     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7901     color = getPixelColor(device, 320, 240-32);
7902     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7903     color = getPixelColor(device, 320, 240+32);
7904     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7905     color = getPixelColor(device, 320, 240);
7906     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7907     color = getPixelColor(device, 320+32, 240+32);
7908     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7909     color = getPixelColor(device, 320-32, 240+32);
7910     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7911     color = getPixelColor(device, 320+32, 240-32);
7912     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7913     color = getPixelColor(device, 320-32, 240-32);
7914     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7915
7916     for(i = 0; i < 2; i++) {
7917         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7918         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7919         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7920         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7921         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7922         IDirect3DTexture9_Release(texture); /* To destroy it */
7923     }
7924
7925     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7926         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7927         goto cleanup;
7928     }
7929     if(L6V5U5_supported == FALSE) {
7930         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7931         goto cleanup;
7932     }
7933
7934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7935     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7936     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7937      * would only make this test more complicated
7938      */
7939     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7940     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7941     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7942     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7943
7944     memset(&locked_rect, 0, sizeof(locked_rect));
7945     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7946     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7947     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7948     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7949     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7950
7951     memset(&locked_rect, 0, sizeof(locked_rect));
7952     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7953     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7954     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7955     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7956     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7957
7958     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7959     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7960     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7961     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7962
7963     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7964     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7965     scale = 2.0;
7966     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7967     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7968     offset = 0.1;
7969     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7970     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7971
7972     hr = IDirect3DDevice9_BeginScene(device);
7973     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7974     if(SUCCEEDED(hr)) {
7975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7976         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7977         hr = IDirect3DDevice9_EndScene(device);
7978         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7979     }
7980
7981     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7982     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7983     color = getPixelColor(device, 320, 240);
7984     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7985      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7986      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7987      */
7988     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7989
7990     /* Check a result scale factor > 1.0 */
7991     scale = 10;
7992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7993     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7994     offset = 10;
7995     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7996     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7997
7998     hr = IDirect3DDevice9_BeginScene(device);
7999     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8000     if(SUCCEEDED(hr)) {
8001         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8002         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8003         hr = IDirect3DDevice9_EndScene(device);
8004         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8005     }
8006     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8007     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8008     color = getPixelColor(device, 320, 240);
8009     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8010
8011     /* Check clamping in the scale factor calculation */
8012     scale = 1000;
8013     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8014     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8015     offset = -1;
8016     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8017     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8018
8019     hr = IDirect3DDevice9_BeginScene(device);
8020     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8021     if(SUCCEEDED(hr)) {
8022         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8023         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8024         hr = IDirect3DDevice9_EndScene(device);
8025         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8026     }
8027     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8028     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8029     color = getPixelColor(device, 320, 240);
8030     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8031
8032     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8033     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8034     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8035     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8036
8037     IDirect3DTexture9_Release(tex1);
8038     IDirect3DTexture9_Release(tex2);
8039
8040 cleanup:
8041     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8042     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8043     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8044     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8045
8046     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8047     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8048     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8049 }
8050
8051 static void stencil_cull_test(IDirect3DDevice9 *device) {
8052     HRESULT hr;
8053     IDirect3DSurface9 *depthstencil = NULL;
8054     D3DSURFACE_DESC desc;
8055     float quad1[] = {
8056         -1.0,   -1.0,   0.1,
8057          0.0,   -1.0,   0.1,
8058         -1.0,    0.0,   0.1,
8059          0.0,    0.0,   0.1,
8060     };
8061     float quad2[] = {
8062          0.0,   -1.0,   0.1,
8063          1.0,   -1.0,   0.1,
8064          0.0,    0.0,   0.1,
8065          1.0,    0.0,   0.1,
8066     };
8067     float quad3[] = {
8068         0.0,    0.0,   0.1,
8069         1.0,    0.0,   0.1,
8070         0.0,    1.0,   0.1,
8071         1.0,    1.0,   0.1,
8072     };
8073     float quad4[] = {
8074         -1.0,    0.0,   0.1,
8075          0.0,    0.0,   0.1,
8076         -1.0,    1.0,   0.1,
8077          0.0,    1.0,   0.1,
8078     };
8079     struct vertex painter[] = {
8080        {-1.0,   -1.0,   0.0,    0x00000000},
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     };
8085     WORD indices_cw[]  = {0, 1, 3};
8086     WORD indices_ccw[] = {0, 2, 3};
8087     unsigned int i;
8088     DWORD color;
8089
8090     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8091     if(depthstencil == NULL) {
8092         skip("No depth stencil buffer\n");
8093         return;
8094     }
8095     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8096     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8097     IDirect3DSurface9_Release(depthstencil);
8098     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8099         skip("No 4 or 8 bit stencil surface\n");
8100         return;
8101     }
8102
8103     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8104     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8105     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8106
8107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8110     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8113     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8114     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8115
8116     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8117     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8118     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8119     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8120     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8121     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8122
8123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8124     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8126     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127
8128     /* First pass: Fill the stencil buffer with some values... */
8129     hr = IDirect3DDevice9_BeginScene(device);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8131     if(SUCCEEDED(hr))
8132     {
8133         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8134         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8135         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8136                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8137         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8138                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8139
8140         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8141         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8144         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8145                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8146         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8147                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8148
8149         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8150         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8151         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8152                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8153         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8154                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8155
8156         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8157         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8158         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8159                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8160         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8161                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8162
8163         hr = IDirect3DDevice9_EndScene(device);
8164         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8165     }
8166
8167     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8168     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8169     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8170     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8171     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8173     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8174     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8175     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8176     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8177     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8179     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8180
8181     /* 2nd pass: Make the stencil values visible */
8182     hr = IDirect3DDevice9_BeginScene(device);
8183     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8184     if(SUCCEEDED(hr))
8185     {
8186         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8187         for(i = 0; i < 16; i++) {
8188             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8189             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8190
8191             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8192             painter[1].diffuse = (i * 16);
8193             painter[2].diffuse = (i * 16);
8194             painter[3].diffuse = (i * 16);
8195             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8196             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8197         }
8198         hr = IDirect3DDevice9_EndScene(device);
8199         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8200     }
8201
8202     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8203     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8204
8205     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8206     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8207
8208     color = getPixelColor(device, 160, 420);
8209     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8210     color = getPixelColor(device, 160, 300);
8211     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8212
8213     color = getPixelColor(device, 480, 420);
8214     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8215     color = getPixelColor(device, 480, 300);
8216     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8217
8218     color = getPixelColor(device, 160, 180);
8219     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8220     color = getPixelColor(device, 160, 60);
8221     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8222
8223     color = getPixelColor(device, 480, 180);
8224     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8225     color = getPixelColor(device, 480, 60);
8226     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8227 }
8228
8229 static void vpos_register_test(IDirect3DDevice9 *device)
8230 {
8231     HRESULT hr;
8232     DWORD color;
8233     const DWORD shader_code[] = {
8234     0xffff0300,                                                             /* ps_3_0                     */
8235     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8236     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8237     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8238     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8239     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8240     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8241     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8242     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8243     0x0000ffff                                                              /* end                        */
8244     };
8245     const DWORD shader_frac_code[] = {
8246     0xffff0300,                                                             /* ps_3_0                     */
8247     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8248     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8249     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8250     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8251     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8252     0x0000ffff                                                              /* end                        */
8253     };
8254     IDirect3DPixelShader9 *shader, *shader_frac;
8255     IDirect3DSurface9 *surface = NULL, *backbuffer;
8256     const float quad[] = {
8257         -1.0,   -1.0,   0.1,    0.0,    0.0,
8258          1.0,   -1.0,   0.1,    1.0,    0.0,
8259         -1.0,    1.0,   0.1,    0.0,    1.0,
8260          1.0,    1.0,   0.1,    1.0,    1.0,
8261     };
8262     D3DLOCKED_RECT lr;
8263     float constant[4] = {1.0, 0.0, 320, 240};
8264     DWORD *pos;
8265
8266     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8267     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8268     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8269     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8270     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8271     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8272     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8273     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8274     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8275     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8276     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8277     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8278
8279     hr = IDirect3DDevice9_BeginScene(device);
8280     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8281     if(SUCCEEDED(hr)) {
8282         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8283         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8284         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8285         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8286         hr = IDirect3DDevice9_EndScene(device);
8287         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8288     }
8289
8290     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8291     /* This has to be pixel exact */
8292     color = getPixelColor(device, 319, 239);
8293     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8294     color = getPixelColor(device, 320, 239);
8295     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8296     color = getPixelColor(device, 319, 240);
8297     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8298     color = getPixelColor(device, 320, 240);
8299     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8300
8301     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8302                                              &surface, NULL);
8303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8304     hr = IDirect3DDevice9_BeginScene(device);
8305     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8306     if(SUCCEEDED(hr)) {
8307         constant[2] = 16; constant[3] = 16;
8308         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8309         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8310         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8311         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8312         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8313         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8314         hr = IDirect3DDevice9_EndScene(device);
8315         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8316     }
8317     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8318     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8319
8320     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8321     color = *pos & 0x00ffffff;
8322     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8323     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8324     color = *pos & 0x00ffffff;
8325     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8326     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8327     color = *pos & 0x00ffffff;
8328     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8329     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8330     color = *pos & 0x00ffffff;
8331     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8332
8333     hr = IDirect3DSurface9_UnlockRect(surface);
8334     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8335
8336     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8337      * have full control over the multisampling setting inside this test
8338      */
8339     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8340     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8341     hr = IDirect3DDevice9_BeginScene(device);
8342     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8343     if(SUCCEEDED(hr)) {
8344         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8345         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8346         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8347         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8348         hr = IDirect3DDevice9_EndScene(device);
8349         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8350     }
8351     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8352     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8353
8354     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8355     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8356
8357     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8358     color = *pos & 0x00ffffff;
8359     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8360
8361     hr = IDirect3DSurface9_UnlockRect(surface);
8362     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8363
8364     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8365     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8366     IDirect3DPixelShader9_Release(shader);
8367     IDirect3DPixelShader9_Release(shader_frac);
8368     if(surface) IDirect3DSurface9_Release(surface);
8369     IDirect3DSurface9_Release(backbuffer);
8370 }
8371
8372 static void pointsize_test(IDirect3DDevice9 *device)
8373 {
8374     HRESULT hr;
8375     D3DCAPS9 caps;
8376     D3DMATRIX matrix;
8377     D3DMATRIX identity;
8378     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8379     DWORD color;
8380     IDirect3DTexture9 *tex1, *tex2;
8381     D3DLOCKED_RECT lr;
8382     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8383                                 0x00000000, 0x00000000};
8384     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8385                                 0x00000000, 0x0000ff00};
8386
8387     const float vertices[] = {
8388         64,     64,     0.1,
8389         128,    64,     0.1,
8390         192,    64,     0.1,
8391         256,    64,     0.1,
8392         320,    64,     0.1,
8393         384,    64,     0.1,
8394         448,    64,     0.1,
8395         512,    64,     0.1,
8396         576,    64,     0.1,
8397     };
8398
8399     /* 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 */
8400     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;
8401     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;
8402     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;
8403     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;
8404
8405     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;
8406     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;
8407     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;
8408     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;
8409
8410     memset(&caps, 0, sizeof(caps));
8411     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8412     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8413     if(caps.MaxPointSize < 32.0) {
8414         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8415         return;
8416     }
8417
8418     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8419     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8420     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8422     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8423     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8424     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8425     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8426
8427     hr = IDirect3DDevice9_BeginScene(device);
8428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8429     if(SUCCEEDED(hr)) {
8430         ptsize = 16.0;
8431         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8432         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8433         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8434         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8435
8436         ptsize = 32.0;
8437         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8438         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8439         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8440         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8441
8442         ptsize = 31.5;
8443         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8444         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8446         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8447
8448         if(caps.MaxPointSize >= 64.0) {
8449             ptsize = 64.0;
8450             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8451             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8452             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8453             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8454
8455             ptsize = 63.75;
8456             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8457             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8458             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8459             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8460         }
8461
8462         ptsize = 1.0;
8463         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8464         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8465         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8466         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8467
8468         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8469         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8470         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8471         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8472
8473         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8474         ptsize = 16.0;
8475         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8476         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8477         ptsize = 1.0;
8478         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8479         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8480         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8481         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8482
8483         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8484          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8485          */
8486         ptsize = 4.0;
8487         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8488         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8489         ptsize = 16.0;
8490         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8491         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8492         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8493         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8494
8495         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8496         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8497
8498         /* pointsize < pointsize_min < pointsize_max?
8499          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8500          */
8501         ptsize = 1.0;
8502         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8503         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8504         ptsize = 16.0;
8505         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8506         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8507         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8508         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8509
8510         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8511         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8512
8513         hr = IDirect3DDevice9_EndScene(device);
8514         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8515     }
8516     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8517     color = getPixelColor(device, 64-9, 64-9);
8518     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8519     color = getPixelColor(device, 64-8, 64-8);
8520     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8521     color = getPixelColor(device, 64-7, 64-7);
8522     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8523     color = getPixelColor(device, 64+7, 64+7);
8524     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8525     color = getPixelColor(device, 64+8, 64+8);
8526     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8527     color = getPixelColor(device, 64+9, 64+9);
8528     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8529
8530     color = getPixelColor(device, 128-17, 64-17);
8531     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8532     color = getPixelColor(device, 128-16, 64-16);
8533     todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8534     color = getPixelColor(device, 128-15, 64-15);
8535     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8536     color = getPixelColor(device, 128+15, 64+15);
8537     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8538     color = getPixelColor(device, 128+16, 64+16);
8539     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8540     color = getPixelColor(device, 128+17, 64+17);
8541     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8542
8543     color = getPixelColor(device, 192-17, 64-17);
8544     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8545     color = getPixelColor(device, 192-16, 64-16);
8546     ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8547     color = getPixelColor(device, 192-15, 64-15);
8548     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8549     color = getPixelColor(device, 192+15, 64+15);
8550     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8551     color = getPixelColor(device, 192+16, 64+16);
8552     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8553     color = getPixelColor(device, 192+17, 64+17);
8554     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8555
8556     if(caps.MaxPointSize >= 64.0) {
8557         color = getPixelColor(device, 256-33, 64-33);
8558         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8559         color = getPixelColor(device, 256-32, 64-32);
8560         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8561         color = getPixelColor(device, 256-31, 64-31);
8562         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8563         color = getPixelColor(device, 256+31, 64+31);
8564         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8565         color = getPixelColor(device, 256+32, 64+32);
8566         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8567         color = getPixelColor(device, 256+33, 64+33);
8568         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8569
8570         color = getPixelColor(device, 384-33, 64-33);
8571         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8572         color = getPixelColor(device, 384-32, 64-32);
8573         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8574         color = getPixelColor(device, 384-31, 64-31);
8575         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8576         color = getPixelColor(device, 384+31, 64+31);
8577         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8578         color = getPixelColor(device, 384+32, 64+32);
8579         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8580         color = getPixelColor(device, 384+33, 64+33);
8581         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8582     }
8583
8584     color = getPixelColor(device, 320-1, 64-1);
8585     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8586     color = getPixelColor(device, 320-0, 64-0);
8587     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8588     color = getPixelColor(device, 320+1, 64+1);
8589     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8590
8591     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8592     color = getPixelColor(device, 448-4, 64-4);
8593     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8594     color = getPixelColor(device, 448+4, 64+4);
8595     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8596
8597     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8598     color = getPixelColor(device, 512-4, 64-4);
8599     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8600     color = getPixelColor(device, 512+4, 64+4);
8601     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8602
8603     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8604      * Don't be overly picky - just show that the point is bigger than 1 pixel
8605      */
8606     color = getPixelColor(device, 576-4, 64-4);
8607     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8608     color = getPixelColor(device, 576+4, 64+4);
8609     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8610
8611     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8612      * generates texture coordinates for the point(result: Yes, it does)
8613      *
8614      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8615      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8616      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8617      */
8618     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8619     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8620
8621     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8622     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8623     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8624     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8625     memset(&lr, 0, sizeof(lr));
8626     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8627     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8628     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8629     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8630     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8631     memset(&lr, 0, sizeof(lr));
8632     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8633     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8634     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8635     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8636     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8637     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8638     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8639     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8640     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8641     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8642     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8643     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8644     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8645     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8646     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8647     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8648     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8649     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8650     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8651
8652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8654     ptsize = 32.0;
8655     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8656     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8657
8658     hr = IDirect3DDevice9_BeginScene(device);
8659     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8660     if(SUCCEEDED(hr))
8661     {
8662         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8663         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8664         hr = IDirect3DDevice9_EndScene(device);
8665         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8666     }
8667
8668     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8669     color = getPixelColor(device, 64-4, 64-4);
8670     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8671     color = getPixelColor(device, 64-4, 64+4);
8672     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8673     color = getPixelColor(device, 64+4, 64+4);
8674     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8675     color = getPixelColor(device, 64+4, 64-4);
8676     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8677
8678     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8679     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8680     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8681     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8682     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8683     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8684     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8685     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8686     IDirect3DTexture9_Release(tex1);
8687     IDirect3DTexture9_Release(tex2);
8688
8689     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8690     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8691     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8692     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8693     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8694     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8695 }
8696
8697 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8698 {
8699     HRESULT hr;
8700     IDirect3DPixelShader9 *ps;
8701     IDirect3DTexture9 *tex1, *tex2;
8702     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8703     D3DCAPS9 caps;
8704     DWORD color;
8705     DWORD shader_code[] = {
8706     0xffff0300,                                                             /* ps_3_0             */
8707     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8708     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8709     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8710     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8711     0x0000ffff                                                              /* END                */
8712     };
8713     float quad[] = {
8714        -1.0,   -1.0,    0.1,
8715         1.0,   -1.0,    0.1,
8716        -1.0,    1.0,    0.1,
8717         1.0,    1.0,    0.1,
8718     };
8719     float texquad[] = {
8720        -1.0,   -1.0,    0.1,    0.0,    0.0,
8721         0.0,   -1.0,    0.1,    1.0,    0.0,
8722        -1.0,    1.0,    0.1,    0.0,    1.0,
8723         0.0,    1.0,    0.1,    1.0,    1.0,
8724
8725         0.0,   -1.0,    0.1,    0.0,    0.0,
8726         1.0,   -1.0,    0.1,    1.0,    0.0,
8727         0.0,    1.0,    0.1,    0.0,    1.0,
8728         1.0,    1.0,    0.1,    1.0,    1.0,
8729     };
8730
8731     memset(&caps, 0, sizeof(caps));
8732     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8733     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8734     if(caps.NumSimultaneousRTs < 2) {
8735         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8736         return;
8737     }
8738
8739     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8740     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8741
8742     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8743     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8744     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8745     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8746     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8747     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8748
8749     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8750     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8751     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8752     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8753     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8754     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8755
8756     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8757     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8758     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8759     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8760     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8761     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8762     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8763     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8764
8765     hr = IDirect3DDevice9_BeginScene(device);
8766     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8767     if(SUCCEEDED(hr)) {
8768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8769         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8770
8771         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8773         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8775         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8776         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8777         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8778         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8779
8780         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8781         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8782         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8783         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8784
8785         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8786         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8787         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8788         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8789
8790         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8791         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8792
8793         hr = IDirect3DDevice9_EndScene(device);
8794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8795     }
8796
8797     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8798     color = getPixelColor(device, 160, 240);
8799     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8800     color = getPixelColor(device, 480, 240);
8801     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8802
8803     IDirect3DPixelShader9_Release(ps);
8804     IDirect3DTexture9_Release(tex1);
8805     IDirect3DTexture9_Release(tex2);
8806     IDirect3DSurface9_Release(surf1);
8807     IDirect3DSurface9_Release(surf2);
8808     IDirect3DSurface9_Release(backbuf);
8809 }
8810
8811 struct formats {
8812     const char *fmtName;
8813     D3DFORMAT textureFormat;
8814     DWORD resultColorBlending;
8815     DWORD resultColorNoBlending;
8816 };
8817
8818 const struct formats test_formats[] = {
8819   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8820   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8821   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8822   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8823   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8824   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8825   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8826   { NULL, 0 }
8827 };
8828
8829 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8830 {
8831     HRESULT hr;
8832     IDirect3DTexture9 *offscreenTexture = NULL;
8833     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8834     IDirect3D9 *d3d = NULL;
8835     DWORD color;
8836     DWORD r0, g0, b0, r1, g1, b1;
8837     int fmt_index;
8838
8839     static const float quad[][5] = {
8840         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8841         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8842         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8843         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8844     };
8845
8846     /* Quad with R=0x10, G=0x20 */
8847     static const struct vertex quad1[] = {
8848         {-1.0f, -1.0f, 0.1f, 0x80102000},
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     };
8853
8854     /* Quad with R=0x20, G=0x10 */
8855     static const struct vertex quad2[] = {
8856         {-1.0f, -1.0f, 0.1f, 0x80201000},
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     };
8861
8862     IDirect3DDevice9_GetDirect3D(device, &d3d);
8863
8864     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8865     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8866     if(!backbuffer) {
8867         goto out;
8868     }
8869
8870     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8871     {
8872         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8873         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8874            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8875            continue;
8876         }
8877
8878         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8879         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8880
8881         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8882         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8883         if(!offscreenTexture) {
8884             continue;
8885         }
8886
8887         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8888         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8889         if(!offscreen) {
8890             continue;
8891         }
8892
8893         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8894         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8895
8896         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8897         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8898         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8899         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8900         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8901         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8902         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8903         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8904         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8905         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8906
8907         /* Below we will draw two quads with different colors and try to blend them together.
8908          * The result color is compared with the expected outcome.
8909          */
8910         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8911             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8912             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8913             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8914             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8915
8916             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8917             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8918
8919             /* Draw a quad using color 0x0010200 */
8920             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8921             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8922             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8923             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8924             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8925             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8926
8927             /* Draw a quad using color 0x0020100 */
8928             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8929             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8930             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8931             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8932             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8933             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8934
8935             /* We don't want to blend the result on the backbuffer */
8936             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8937             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8938
8939             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8940             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8941             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8942             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8943             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8944
8945             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8946             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8947
8948             /* This time with the texture */
8949             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8950             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8951
8952             IDirect3DDevice9_EndScene(device);
8953         }
8954         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8955
8956
8957         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8958             /* Compare the color of the center quad with our expectation */
8959             color = getPixelColor(device, 320, 240);
8960             r0 = (color & 0x00ff0000) >> 16;
8961             g0 = (color & 0x0000ff00) >>  8;
8962             b0 = (color & 0x000000ff) >>  0;
8963
8964             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8965             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8966             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8967
8968             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8969                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8970                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8971                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8972         } else {
8973             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8974              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8975              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8976             color = getPixelColor(device, 320, 240);
8977             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);
8978         }
8979
8980         IDirect3DDevice9_SetTexture(device, 0, NULL);
8981         if(offscreenTexture) {
8982             IDirect3DTexture9_Release(offscreenTexture);
8983         }
8984         if(offscreen) {
8985             IDirect3DSurface9_Release(offscreen);
8986         }
8987     }
8988
8989 out:
8990     /* restore things */
8991     if(backbuffer) {
8992         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8993         IDirect3DSurface9_Release(backbuffer);
8994     }
8995 }
8996
8997 static void tssargtemp_test(IDirect3DDevice9 *device)
8998 {
8999     HRESULT hr;
9000     DWORD color;
9001     static const struct vertex quad[] = {
9002         {-1.0,     -1.0,    0.1,    0x00ff0000},
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     };
9007     D3DCAPS9 caps;
9008
9009     memset(&caps, 0, sizeof(caps));
9010     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9011     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9012     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9013         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9014         return;
9015     }
9016
9017     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9018     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9019
9020     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9021     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9022     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9023     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9024
9025     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9026     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9027     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9028     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9029     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9030     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9031
9032     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9033     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9034     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9035     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9036     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9037     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9038
9039     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9040     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9041
9042     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9043     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9044     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9045     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9046
9047     hr = IDirect3DDevice9_BeginScene(device);
9048     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9049     if(SUCCEEDED(hr)) {
9050
9051         hr = IDirect3DDevice9_EndScene(device);
9052         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9054         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9055     }
9056     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9057     color = getPixelColor(device, 320, 240);
9058     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9059
9060     /* Set stage 1 back to default */
9061     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9062     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9063     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9064     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9065     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9066     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9067     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9068     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9069     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9070     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9071 }
9072
9073 struct testdata
9074 {
9075     DWORD idxVertex; /* number of instances in the first stream */
9076     DWORD idxColor; /* number of instances in the second stream */
9077     DWORD idxInstance; /* should be 1 ?? */
9078     DWORD color1; /* color 1 instance */
9079     DWORD color2; /* color 2 instance */
9080     DWORD color3; /* color 3 instance */
9081     DWORD color4; /* color 4 instance */
9082     WORD strVertex; /* specify which stream to use 0-2*/
9083     WORD strColor;
9084     WORD strInstance;
9085 };
9086
9087 static const struct testdata testcases[]=
9088 {
9089     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9090     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9091     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9092     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9093     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9094     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9095     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9096     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9097     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9098     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9099     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9100     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9101     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9102     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9103     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9104 /*
9105     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9106     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9107 */
9108 };
9109
9110 /* Drawing Indexed Geometry with instances*/
9111 static void stream_test(IDirect3DDevice9 *device)
9112 {
9113     IDirect3DVertexBuffer9 *vb = NULL;
9114     IDirect3DVertexBuffer9 *vb2 = NULL;
9115     IDirect3DVertexBuffer9 *vb3 = NULL;
9116     IDirect3DIndexBuffer9 *ib = NULL;
9117     IDirect3DVertexDeclaration9 *pDecl = NULL;
9118     IDirect3DVertexShader9 *shader = NULL;
9119     HRESULT hr;
9120     BYTE *data;
9121     DWORD color;
9122     DWORD ind;
9123     unsigned i;
9124
9125     const DWORD shader_code[] =
9126     {
9127         0xfffe0101,                                     /* vs_1_1 */
9128         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9129         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9130         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9131         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9132         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9133         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9134         0x0000ffff
9135     };
9136
9137     const float quad[][3] =
9138     {
9139         {-0.5f, -0.5f,  1.1f}, /*0 */
9140         {-0.5f,  0.5f,  1.1f}, /*1 */
9141         { 0.5f, -0.5f,  1.1f}, /*2 */
9142         { 0.5f,  0.5f,  1.1f}, /*3 */
9143     };
9144
9145     const float vertcolor[][4] =
9146     {
9147         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9148         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9149         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9150         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9151     };
9152
9153     /* 4 position for 4 instances */
9154     const float instancepos[][3] =
9155     {
9156         {-0.6f,-0.6f, 0.0f},
9157         { 0.6f,-0.6f, 0.0f},
9158         { 0.6f, 0.6f, 0.0f},
9159         {-0.6f, 0.6f, 0.0f},
9160     };
9161
9162     short indices[] = {0, 1, 2, 1, 2, 3};
9163
9164     D3DVERTEXELEMENT9 decl[] =
9165     {
9166         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9167         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9168         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9169         D3DDECL_END()
9170     };
9171
9172     /* set the default value because it isn't done in wine? */
9173     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9174     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9175
9176     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9177     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9178     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9179
9180     /* check wrong cases */
9181     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9182     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9183     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9184     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9185     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9186     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9187     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9188     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9189     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9190     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9191     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9192     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9193     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9194     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9195     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9196     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9197     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9198     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9199     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9200     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9201
9202     /* set the default value back */
9203     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9204     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9205
9206     /* create all VertexBuffers*/
9207     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9208     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9209     if(!vb) {
9210         skip("Failed to create a vertex buffer\n");
9211         return;
9212     }
9213     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9214     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9215     if(!vb2) {
9216         skip("Failed to create a vertex buffer\n");
9217         goto out;
9218     }
9219     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9220     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9221     if(!vb3) {
9222         skip("Failed to create a vertex buffer\n");
9223         goto out;
9224     }
9225
9226     /* create IndexBuffer*/
9227     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9228     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9229     if(!ib) {
9230         skip("Failed to create a index buffer\n");
9231         goto out;
9232     }
9233
9234     /* copy all Buffers (Vertex + Index)*/
9235     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9236     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9237     memcpy(data, quad, sizeof(quad));
9238     hr = IDirect3DVertexBuffer9_Unlock(vb);
9239     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9240     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9241     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9242     memcpy(data, vertcolor, sizeof(vertcolor));
9243     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9244     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9245     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9246     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9247     memcpy(data, instancepos, sizeof(instancepos));
9248     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9249     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9250     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9251     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9252     memcpy(data, indices, sizeof(indices));
9253     hr = IDirect3DIndexBuffer9_Unlock(ib);
9254     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9255
9256     /* create VertexShader */
9257     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9258     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9259     if(!shader) {
9260         skip("Failed to create a vetex shader\n");
9261         goto out;
9262     }
9263
9264     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9265     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9266
9267     hr = IDirect3DDevice9_SetIndices(device, ib);
9268     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9269
9270     /* run all tests */
9271     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9272     {
9273         struct testdata act = testcases[i];
9274         decl[0].Stream = act.strVertex;
9275         decl[1].Stream = act.strColor;
9276         decl[2].Stream = act.strInstance;
9277         /* create VertexDeclarations */
9278         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9279         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9280
9281         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9282         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9283
9284         hr = IDirect3DDevice9_BeginScene(device);
9285         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9286         if(SUCCEEDED(hr))
9287         {
9288             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9289             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9290
9291             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9292             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9293             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9294             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9295
9296             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9297             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9298             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9299             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9300
9301             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9302             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9303             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9304             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9305
9306             /* don't know if this is right (1*3 and 4*1)*/
9307             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9308             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9309             hr = IDirect3DDevice9_EndScene(device);
9310             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9311
9312             /* set all StreamSource && StreamSourceFreq back to default */
9313             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9314             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9315             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9316             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9317             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9318             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9319             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9320             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9321             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9322             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9323             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9324             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9325         }
9326
9327         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9328         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9329
9330         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9331         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9332
9333         color = getPixelColor(device, 160, 360);
9334         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9335         color = getPixelColor(device, 480, 360);
9336         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9337         color = getPixelColor(device, 480, 120);
9338         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9339         color = getPixelColor(device, 160, 120);
9340         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9341     }
9342
9343     hr = IDirect3DDevice9_SetIndices(device, NULL);
9344     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9345
9346 out:
9347     if(vb) IDirect3DVertexBuffer9_Release(vb);
9348     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9349     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9350     if(ib)IDirect3DIndexBuffer9_Release(ib);
9351     if(shader)IDirect3DVertexShader9_Release(shader);
9352 }
9353
9354 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9355     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9356     IDirect3DTexture9 *dsttex = NULL;
9357     HRESULT hr;
9358     DWORD color;
9359     D3DRECT r1 = {0,  0,  50,  50 };
9360     D3DRECT r2 = {50, 0,  100, 50 };
9361     D3DRECT r3 = {50, 50, 100, 100};
9362     D3DRECT r4 = {0,  50,  50, 100};
9363     const float quad[] = {
9364         -1.0,   -1.0,   0.1,    0.0,    0.0,
9365          1.0,   -1.0,   0.1,    1.0,    0.0,
9366         -1.0,    1.0,   0.1,    0.0,    1.0,
9367          1.0,    1.0,   0.1,    1.0,    1.0,
9368     };
9369
9370     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9371     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9372
9373     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9374     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9375     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9376     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9377
9378     if(!src || !dsttex) {
9379         skip("One or more test resources could not be created\n");
9380         goto cleanup;
9381     }
9382
9383     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9384     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9385
9386     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9387     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9388
9389     /* Clear the StretchRect destination for debugging */
9390     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9391     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9392     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9393     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9394
9395     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9396     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9397
9398     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9399     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9400     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9401     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9402     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9403     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9404     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9405     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9406
9407     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9408      * the target -> texture GL blit path
9409      */
9410     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9411     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9412     IDirect3DSurface9_Release(dst);
9413
9414     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9415     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9416
9417     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9418     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9419     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9420     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9421     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9422     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9423     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9424     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9425
9426     hr = IDirect3DDevice9_BeginScene(device);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9428     if(SUCCEEDED(hr)) {
9429         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9430         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9431         hr = IDirect3DDevice9_EndScene(device);
9432         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9433     }
9434
9435     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9436     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9437     color = getPixelColor(device, 160, 360);
9438     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9439     color = getPixelColor(device, 480, 360);
9440     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9441     color = getPixelColor(device, 480, 120);
9442     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9443     color = getPixelColor(device, 160, 120);
9444     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9445
9446     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9447     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9448     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9449     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9450
9451 cleanup:
9452     if(src) IDirect3DSurface9_Release(src);
9453     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9454     if(dsttex) IDirect3DTexture9_Release(dsttex);
9455 }
9456
9457 static void texop_test(IDirect3DDevice9 *device)
9458 {
9459     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9460     IDirect3DTexture9 *texture = NULL;
9461     D3DLOCKED_RECT locked_rect;
9462     D3DCOLOR color;
9463     D3DCAPS9 caps;
9464     HRESULT hr;
9465     unsigned i;
9466
9467     static const struct {
9468         float x, y, z;
9469         float s, t;
9470         D3DCOLOR diffuse;
9471     } quad[] = {
9472         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
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     };
9477
9478     static const D3DVERTEXELEMENT9 decl_elements[] = {
9479         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9480         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9481         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9482         D3DDECL_END()
9483     };
9484
9485     static const struct {
9486         D3DTEXTUREOP op;
9487         const char *name;
9488         DWORD caps_flag;
9489         D3DCOLOR result;
9490     } test_data[] = {
9491         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9492         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9493         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9494         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9495         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9496         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9497         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9498         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9499         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9500         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9501         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9502         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9503         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9504         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9505         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9506         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9507         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9508         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9509         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9510         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9511         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT2",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9512         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9513         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9514     };
9515
9516     memset(&caps, 0, sizeof(caps));
9517     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9518     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9519
9520     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9521     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9522     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9523     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9524
9525     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9526     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9527     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9528     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9529     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9530     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9531     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9532     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9533     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9534
9535     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9536     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9537     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9538     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9539     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9540     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9541
9542     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9543     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9544
9545     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9546     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9547     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9548     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9550     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9551
9552     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9553     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9554
9555     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9556     {
9557         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9558         {
9559             skip("tex operation %s not supported\n", test_data[i].name);
9560             continue;
9561         }
9562
9563         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9564         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9565
9566         hr = IDirect3DDevice9_BeginScene(device);
9567         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9568
9569         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9570         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9571
9572         hr = IDirect3DDevice9_EndScene(device);
9573         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9574
9575         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9576         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9577
9578         color = getPixelColor(device, 320, 240);
9579         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9580                 test_data[i].name, color, test_data[i].result);
9581     }
9582
9583     if (texture) IDirect3DTexture9_Release(texture);
9584     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9585 }
9586
9587 static void yuv_color_test(IDirect3DDevice9 *device) {
9588     HRESULT hr;
9589     IDirect3DSurface9 *surface = NULL, *target = NULL;
9590     unsigned int fmt, i;
9591     D3DFORMAT format;
9592     const char *fmt_string;
9593     D3DLOCKED_RECT lr;
9594     IDirect3D9 *d3d;
9595     HRESULT color;
9596     DWORD ref_color_left, ref_color_right;
9597
9598     struct {
9599         DWORD in;           /* The input color */
9600         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9601         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9602         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9603         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9604     } test_data[] = {
9605     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9606      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9607      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9608      * that
9609      */
9610       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9611       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9612       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9613       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9614       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9615       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9616       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9617       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9618       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9619       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9620       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9621       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9622       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9623       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9624
9625       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9626       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9627       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9628       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9629     };
9630
9631     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9632     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9633     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9634     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9635
9636     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9637     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9638
9639     for(fmt = 0; fmt < 2; fmt++) {
9640         if(fmt == 0) {
9641             format = D3DFMT_UYVY;
9642             fmt_string = "D3DFMT_UYVY";
9643         } else {
9644             format = D3DFMT_YUY2;
9645             fmt_string = "D3DFMT_YUY2";
9646         }
9647
9648         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9649                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9650                        */
9651         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9652                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9653             skip("%s is not supported\n", fmt_string);
9654             continue;
9655         }
9656
9657         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9658         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9659         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9660
9661         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9662             if(fmt == 0) {
9663                 ref_color_left = test_data[i].uyvy_left;
9664                 ref_color_right = test_data[i].uyvy_right;
9665             } else {
9666                 ref_color_left = test_data[i].yuy2_left;
9667                 ref_color_right = test_data[i].yuy2_right;
9668             }
9669
9670             memset(&lr, 0, sizeof(lr));
9671             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9672             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9673             *((DWORD *) lr.pBits) = test_data[i].in;
9674             hr = IDirect3DSurface9_UnlockRect(surface);
9675             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9676
9677             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9678             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9679             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9680             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9681             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9682             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9683
9684             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9685              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9686              * want to add tests for the filtered pixels as well.
9687              *
9688              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9689              * differently, so we need a max diff of 16
9690              */
9691             color = getPixelColor(device, 40, 240);
9692             ok(color_match(color, ref_color_left, 16),
9693                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9694                test_data[i].in, color, ref_color_left, fmt_string);
9695             color = getPixelColor(device, 600, 240);
9696             ok(color_match(color, ref_color_right, 16),
9697                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9698                test_data[i].in, color, ref_color_right, fmt_string);
9699         }
9700         IDirect3DSurface9_Release(surface);
9701     }
9702     IDirect3DSurface9_Release(target);
9703     IDirect3D9_Release(d3d);
9704 }
9705
9706 static void texop_range_test(IDirect3DDevice9 *device)
9707 {
9708     static const struct {
9709         float x, y, z;
9710         D3DCOLOR diffuse;
9711     } quad[] = {
9712         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
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     };
9717     HRESULT hr;
9718     IDirect3DTexture9 *texture;
9719     D3DLOCKED_RECT locked_rect;
9720     D3DCAPS9 caps;
9721     DWORD color;
9722
9723     /* We need ADD and SUBTRACT operations */
9724     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9725     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9726     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9727         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9728     }
9729     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9730         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9731     }
9732
9733     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9734     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9735     /* Stage 1: result = diffuse(=1.0) + diffuse
9736      * stage 2: result = result - tfactor(= 0.5)
9737      */
9738     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9739     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9740     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9741     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9742     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9743     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9744     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9745     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9746     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9747     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9748     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9749     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9750     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9751     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9752
9753     hr = IDirect3DDevice9_BeginScene(device);
9754     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9755     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9756     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9757     hr = IDirect3DDevice9_EndScene(device);
9758     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9759     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9760     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9761
9762     color = getPixelColor(device, 320, 240);
9763     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9764        color);
9765
9766     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9767     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9768     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9769     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9770     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9771     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9772     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9773     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9774     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9775
9776     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9777      * stage 2: result = result + diffuse(1.0)
9778      */
9779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9780     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9781     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9782     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9783     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9784     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9785     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9786     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9787     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9788     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9789     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9790     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9791     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9792     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9793
9794     hr = IDirect3DDevice9_BeginScene(device);
9795     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9796     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9797     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9798     hr = IDirect3DDevice9_EndScene(device);
9799     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9800     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9801     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9802
9803     color = getPixelColor(device, 320, 240);
9804     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9805        color);
9806
9807     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9808     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9809     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9810     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9811     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9812     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9813     IDirect3DTexture9_Release(texture);
9814 }
9815
9816 static void alphareplicate_test(IDirect3DDevice9 *device) {
9817     struct vertex quad[] = {
9818         { -1.0,    -1.0,    0.1,    0x80ff00ff },
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     };
9823     HRESULT hr;
9824     DWORD color;
9825
9826     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9827     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9828
9829     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9830     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9831
9832     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9833     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9834     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9835     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9836
9837     hr = IDirect3DDevice9_BeginScene(device);
9838     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9839     if(SUCCEEDED(hr)) {
9840         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9841         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9842         hr = IDirect3DDevice9_EndScene(device);
9843         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9844     }
9845
9846     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9847     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9848
9849     color = getPixelColor(device, 320, 240);
9850     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9851        color);
9852
9853     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9854     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9855
9856 }
9857
9858 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9859     HRESULT hr;
9860     D3DCAPS9 caps;
9861     DWORD color;
9862     struct vertex quad[] = {
9863         { -1.0,    -1.0,    0.1,    0x408080c0 },
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     };
9868
9869     memset(&caps, 0, sizeof(caps));
9870     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9871     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9872     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9873         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9874         return;
9875     }
9876
9877     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9878     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9879
9880     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9881     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9882
9883     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9884      * mov r0.a, diffuse.a
9885      * mov r0, r0.a
9886      *
9887      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9888      * 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
9889      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9890      */
9891     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9892     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9893     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9894     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9895     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9896     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9897     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9898     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9899     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9900     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9901     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9902     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9903     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9904     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9905     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9906     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9908     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9909
9910     hr = IDirect3DDevice9_BeginScene(device);
9911     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9912     if(SUCCEEDED(hr)) {
9913         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9914         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9915         hr = IDirect3DDevice9_EndScene(device);
9916         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9917     }
9918
9919     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9920     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9921
9922     color = getPixelColor(device, 320, 240);
9923     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9924        color);
9925
9926     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9927     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9928     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9929     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9930     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9931     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9932 }
9933
9934 static void zwriteenable_test(IDirect3DDevice9 *device) {
9935     HRESULT hr;
9936     DWORD color;
9937     struct vertex quad1[] = {
9938         { -1.0,  -1.0,  0.1,    0x00ff0000},
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     };
9943     struct vertex quad2[] = {
9944         { -1.0,  -1.0,  0.9,    0x0000ff00},
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     };
9949
9950     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9951     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9952
9953     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9954     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9955     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9956     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9957     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9958     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9959     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9961
9962     hr = IDirect3DDevice9_BeginScene(device);
9963     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9964     if(SUCCEEDED(hr)) {
9965         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9966          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9967          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9968          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9969          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9970          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9971          */
9972         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9973         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9974         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9975         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9976         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9977         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9978
9979         hr = IDirect3DDevice9_EndScene(device);
9980         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9981     }
9982
9983     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9984     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9985     color = getPixelColor(device, 320, 240);
9986     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9987        color);
9988
9989     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9990     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9991 }
9992
9993 static void alphatest_test(IDirect3DDevice9 *device) {
9994 #define ALPHATEST_PASSED 0x0000ff00
9995 #define ALPHATEST_FAILED 0x00ff0000
9996     struct {
9997         D3DCMPFUNC  func;
9998         DWORD       color_less;
9999         DWORD       color_equal;
10000         DWORD       color_greater;
10001     } testdata[] = {
10002         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10003         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10004         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10005         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10006         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10007         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10008         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10009         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10010     };
10011     unsigned int i, j;
10012     HRESULT hr;
10013     DWORD color;
10014     struct vertex quad[] = {
10015         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
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     };
10020     D3DCAPS9 caps;
10021
10022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10023     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10024     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10025     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10026
10027     for(j = 0; j < 2; j++) {
10028         if(j == 1) {
10029             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10030              * the alpha test either for performance reasons(floating point RTs) or to work
10031              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10032              * codepath for ffp and shader in this case, and the test should cover both
10033              */
10034             IDirect3DPixelShader9 *ps;
10035             DWORD shader_code[] = {
10036                 0xffff0101,                                 /* ps_1_1           */
10037                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10038                 0x0000ffff                                  /* end              */
10039             };
10040             memset(&caps, 0, sizeof(caps));
10041             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10042             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10043             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10044                 break;
10045             }
10046
10047             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10048             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10049             IDirect3DDevice9_SetPixelShader(device, ps);
10050             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10051             IDirect3DPixelShader9_Release(ps);
10052         }
10053
10054         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10055             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10056             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10057
10058             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10059             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10060             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10061             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10062             hr = IDirect3DDevice9_BeginScene(device);
10063             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10064             if(SUCCEEDED(hr)) {
10065                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10066                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10067                 hr = IDirect3DDevice9_EndScene(device);
10068                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10069             }
10070             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10071             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10072             color = getPixelColor(device, 320, 240);
10073             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10074             color, testdata[i].color_less, testdata[i].func);
10075
10076             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10077             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10078             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10079             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10080             hr = IDirect3DDevice9_BeginScene(device);
10081             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10082             if(SUCCEEDED(hr)) {
10083                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10084                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10085                 hr = IDirect3DDevice9_EndScene(device);
10086                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10087             }
10088             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10089             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10090             color = getPixelColor(device, 320, 240);
10091             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10092             color, testdata[i].color_equal, testdata[i].func);
10093
10094             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10095             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10096             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10097             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10098             hr = IDirect3DDevice9_BeginScene(device);
10099             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10100             if(SUCCEEDED(hr)) {
10101                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10102                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10103                 hr = IDirect3DDevice9_EndScene(device);
10104                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10105             }
10106             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10107             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10108             color = getPixelColor(device, 320, 240);
10109             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10110             color, testdata[i].color_greater, testdata[i].func);
10111         }
10112     }
10113
10114     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10115     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10116     IDirect3DDevice9_SetPixelShader(device, NULL);
10117     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10118 }
10119
10120 static void sincos_test(IDirect3DDevice9 *device) {
10121     const DWORD sin_shader_code[] = {
10122         0xfffe0200,                                                                 /* vs_2_0                       */
10123         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10124         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10125         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10126         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10127         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10128         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10129         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10130         0x0000ffff                                                                  /* end                          */
10131     };
10132     const DWORD cos_shader_code[] = {
10133         0xfffe0200,                                                                 /* vs_2_0                       */
10134         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10135         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10136         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10137         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10138         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10139         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10140         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10141         0x0000ffff                                                                  /* end                          */
10142     };
10143     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10144     HRESULT hr;
10145     struct {
10146         float x, y, z;
10147     } data[1280];
10148     unsigned int i;
10149     float sincosc1[4] = {D3DSINCOSCONST1};
10150     float sincosc2[4] = {D3DSINCOSCONST2};
10151
10152     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10153     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10154
10155     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10156     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10157     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10158     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10159     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10160     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10161     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10162     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10163     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10164     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10165
10166     /* Generate a point from -1 to 1 every 0.5 pixels */
10167     for(i = 0; i < 1280; i++) {
10168         data[i].x = (-640.0 + i) / 640.0;
10169         data[i].y = 0.0;
10170         data[i].z = 0.1;
10171     }
10172
10173     hr = IDirect3DDevice9_BeginScene(device);
10174     if(SUCCEEDED(hr)) {
10175         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10176         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10177         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10178         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10179
10180         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10181         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10182         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10183         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10184
10185         hr = IDirect3DDevice9_EndScene(device);
10186         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10187     }
10188     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10189     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10190
10191     IDirect3DDevice9_SetVertexShader(device, NULL);
10192     IDirect3DVertexShader9_Release(sin_shader);
10193     IDirect3DVertexShader9_Release(cos_shader);
10194 }
10195
10196 static void loop_index_test(IDirect3DDevice9 *device) {
10197     const DWORD shader_code[] = {
10198         0xfffe0200,                                                 /* vs_2_0                   */
10199         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10200         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10201         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10202         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10203         0x0000001d,                                                 /* endloop                  */
10204         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10205         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10206         0x0000ffff                                                  /* END                      */
10207     };
10208     IDirect3DVertexShader9 *shader;
10209     HRESULT hr;
10210     DWORD color;
10211     const float quad[] = {
10212         -1.0,   -1.0,   0.1,
10213          1.0,   -1.0,   0.1,
10214         -1.0,    1.0,   0.1,
10215          1.0,    1.0,   0.1
10216     };
10217     const float zero[4] = {0, 0, 0, 0};
10218     const float one[4] = {1, 1, 1, 1};
10219     int i0[4] = {2, 10, -3, 0};
10220     float values[4];
10221
10222     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10223     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10224     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10225     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10226     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10227     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10228     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10229     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10230
10231     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10232     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10233     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10234     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10235     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10236     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10237     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10238     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10239     values[0] = 1.0;
10240     values[1] = 1.0;
10241     values[2] = 0.0;
10242     values[3] = 0.0;
10243     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10244     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10245     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10246     values[0] = -1.0;
10247     values[1] = 0.0;
10248     values[2] = 0.0;
10249     values[3] = 0.0;
10250     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10251     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10252     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10253     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10254     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10255
10256     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10257
10258     hr = IDirect3DDevice9_BeginScene(device);
10259     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10260     if(SUCCEEDED(hr))
10261     {
10262         trace("going to draw index\n");
10263         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10264         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10265         hr = IDirect3DDevice9_EndScene(device);
10266         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10267     }
10268     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10269     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10270
10271     color = getPixelColor(device, 320, 240);
10272     ok(color_match(color, 0x0000ff00, 1),
10273        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10274
10275     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10277     IDirect3DVertexShader9_Release(shader);
10278 }
10279
10280 static void sgn_test(IDirect3DDevice9 *device) {
10281     const DWORD shader_code[] = {
10282         0xfffe0200,                                                             /* vs_2_0                       */
10283         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10284         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10285         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10286         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10287         0x02000022, 0x800f0000, 0xa0e40000,                                     /* sgn r0, c0                   */
10288         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10289         0x0000ffff                                                              /* end                          */
10290     };
10291     IDirect3DVertexShader9 *shader;
10292     HRESULT hr;
10293     DWORD color;
10294     const float quad[] = {
10295         -1.0,   -1.0,   0.1,
10296          1.0,   -1.0,   0.1,
10297         -1.0,    1.0,   0.1,
10298          1.0,    1.0,   0.1
10299     };
10300
10301     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10302     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10303     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10304     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10305     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10306     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10307     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10308     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10309
10310     hr = IDirect3DDevice9_BeginScene(device);
10311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10312     if(SUCCEEDED(hr))
10313     {
10314         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10315         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10316         hr = IDirect3DDevice9_EndScene(device);
10317         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10318     }
10319     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10320     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10321
10322     color = getPixelColor(device, 320, 240);
10323     ok(color_match(color, 0x008000ff, 1),
10324        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10325
10326     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10327     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10328     IDirect3DVertexShader9_Release(shader);
10329 }
10330
10331 START_TEST(visual)
10332 {
10333     IDirect3DDevice9 *device_ptr;
10334     D3DCAPS9 caps;
10335     HRESULT hr;
10336     DWORD color;
10337
10338     d3d9_handle = LoadLibraryA("d3d9.dll");
10339     if (!d3d9_handle)
10340     {
10341         skip("Could not load d3d9.dll\n");
10342         return;
10343     }
10344
10345     device_ptr = init_d3d9();
10346     if (!device_ptr)
10347     {
10348         skip("Creating the device failed\n");
10349         return;
10350     }
10351
10352     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10353
10354     /* Check for the reliability of the returned data */
10355     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10356     if(FAILED(hr))
10357     {
10358         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10359         goto cleanup;
10360     }
10361     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10362
10363     color = getPixelColor(device_ptr, 1, 1);
10364     if(color !=0x00ff0000)
10365     {
10366         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10367         goto cleanup;
10368     }
10369
10370     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10371     if(FAILED(hr))
10372     {
10373         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10374         goto cleanup;
10375     }
10376     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10377
10378     color = getPixelColor(device_ptr, 639, 479);
10379     if(color != 0x0000ddee)
10380     {
10381         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10382         goto cleanup;
10383     }
10384
10385     /* Now execute the real tests */
10386     stretchrect_test(device_ptr);
10387     lighting_test(device_ptr);
10388     clear_test(device_ptr);
10389     fog_test(device_ptr);
10390     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10391     {
10392         test_cube_wrap(device_ptr);
10393     } else {
10394         skip("No cube texture support\n");
10395     }
10396     z_range_test(device_ptr);
10397     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10398     {
10399         maxmip_test(device_ptr);
10400     }
10401     else
10402     {
10403         skip("No mipmap support\n");
10404     }
10405     offscreen_test(device_ptr);
10406     alpha_test(device_ptr);
10407     shademode_test(device_ptr);
10408     srgbtexture_test(device_ptr);
10409     release_buffer_test(device_ptr);
10410     float_texture_test(device_ptr);
10411     g16r16_texture_test(device_ptr);
10412     pixelshader_blending_test(device_ptr);
10413     texture_transform_flags_test(device_ptr);
10414     autogen_mipmap_test(device_ptr);
10415     fixed_function_decl_test(device_ptr);
10416     conditional_np2_repeat_test(device_ptr);
10417     fixed_function_bumpmap_test(device_ptr);
10418     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10419         stencil_cull_test(device_ptr);
10420     } else {
10421         skip("No two sided stencil support\n");
10422     }
10423     pointsize_test(device_ptr);
10424     tssargtemp_test(device_ptr);
10425     np2_stretch_rect_test(device_ptr);
10426     yuv_color_test(device_ptr);
10427     zwriteenable_test(device_ptr);
10428     alphatest_test(device_ptr);
10429
10430     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10431     {
10432         test_constant_clamp_vs(device_ptr);
10433         test_compare_instructions(device_ptr);
10434     }
10435     else skip("No vs_1_1 support\n");
10436
10437     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10438     {
10439         test_mova(device_ptr);
10440         loop_index_test(device_ptr);
10441         sincos_test(device_ptr);
10442         sgn_test(device_ptr);
10443         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10444             test_vshader_input(device_ptr);
10445             test_vshader_float16(device_ptr);
10446             stream_test(device_ptr);
10447         } else {
10448             skip("No vs_3_0 support\n");
10449         }
10450     }
10451     else skip("No vs_2_0 support\n");
10452
10453     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10454     {
10455         fog_with_shader_test(device_ptr);
10456         fog_srgbwrite_test(device_ptr);
10457     }
10458     else skip("No vs_1_1 and ps_1_1 support\n");
10459
10460     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10461     {
10462         texbem_test(device_ptr);
10463         texdepth_test(device_ptr);
10464         texkill_test(device_ptr);
10465         x8l8v8u8_test(device_ptr);
10466         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10467             constant_clamp_ps_test(device_ptr);
10468             cnd_test(device_ptr);
10469             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10470                 dp2add_ps_test(device_ptr);
10471                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10472                     nested_loop_test(device_ptr);
10473                     fixed_function_varying_test(device_ptr);
10474                     vFace_register_test(device_ptr);
10475                     vpos_register_test(device_ptr);
10476                     multiple_rendertargets_test(device_ptr);
10477                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10478                         vshader_version_varying_test(device_ptr);
10479                         pshader_version_varying_test(device_ptr);
10480                     } else {
10481                         skip("No vs_3_0 support\n");
10482                     }
10483                 } else {
10484                     skip("No ps_3_0 support\n");
10485                 }
10486             } else {
10487                 skip("No ps_2_0 support\n");
10488             }
10489         }
10490     }
10491     else skip("No ps_1_1 support\n");
10492
10493     texop_test(device_ptr);
10494     texop_range_test(device_ptr);
10495     alphareplicate_test(device_ptr);
10496     dp3_alpha_test(device_ptr);
10497
10498 cleanup:
10499     if(device_ptr) {
10500         D3DPRESENT_PARAMETERS present_parameters;
10501         IDirect3DSwapChain9 *swapchain;
10502         ULONG ref;
10503
10504         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10505         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10506         DestroyWindow(present_parameters.hDeviceWindow);
10507         IDirect3DSwapChain9_Release(swapchain);
10508         ref = IDirect3DDevice9_Release(device_ptr);
10509         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10510     }
10511 }