kernel32: Remove superfluous heap reallocation calls in FormatMessageA/W.
[wine] / dlls / d3d9 / tests / visual.c
1 /*
2  * Copyright 2005, 2007-2008 Henri Verbeet
3  * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4  * Copyright (C) 2008 Jason Green(for TransGaming)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22  * the framebuffer, read back from there and compared to expected colors.
23  *
24  * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25  * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26  * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27  * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28  * causes visible results in games can be tested in a way that does not depend on pixel exactness
29  */
30
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
34
35 static HMODULE d3d9_handle = 0;
36
37 static HWND create_window(void)
38 {
39     WNDCLASS wc = {0};
40     HWND ret;
41     wc.lpfnWndProc = DefWindowProc;
42     wc.lpszClassName = "d3d9_test_wc";
43     RegisterClass(&wc);
44
45     ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46                         WS_SYSMENU | WS_POPUP , 0, 0, 640, 480, 0, 0, 0, 0);
47     ShowWindow(ret, SW_SHOW);
48     return ret;
49 }
50
51 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 {
53     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
54     c1 >>= 8; c2 >>= 8;
55     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56     c1 >>= 8; c2 >>= 8;
57     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58     c1 >>= 8; c2 >>= 8;
59     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60     return TRUE;
61 }
62
63 /* Locks a given surface and returns the color at (x,y).  It's the caller's
64  * responsibility to only pass in lockable surfaces and valid x,y coordinates */
65 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 {
67     DWORD color;
68     HRESULT hr;
69     D3DSURFACE_DESC desc;
70     RECT rectToLock = {x, y, x+1, y+1};
71     D3DLOCKED_RECT lockedRect;
72
73     hr = IDirect3DSurface9_GetDesc(surface, &desc);
74     if(FAILED(hr))  /* This is not a test */
75     {
76         trace("Can't get the surface description, hr=%08x\n", hr);
77         return 0xdeadbeef;
78     }
79
80     hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
81     if(FAILED(hr))  /* This is not a test */
82     {
83         trace("Can't lock the surface, hr=%08x\n", hr);
84         return 0xdeadbeef;
85     }
86     switch(desc.Format) {
87         case D3DFMT_A8R8G8B8:
88         {
89             color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
90             break;
91         }
92         default:
93             trace("Error: unknown surface format: %d\n", desc.Format);
94             color = 0xdeadbeef;
95             break;
96     }
97     hr = IDirect3DSurface9_UnlockRect(surface);
98     if(FAILED(hr))
99     {
100         trace("Can't unlock the surface, hr=%08x\n", hr);
101     }
102     return color;
103 }
104
105 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 {
107     DWORD ret;
108     IDirect3DSurface9 *surf = NULL, *target = NULL;
109     HRESULT hr;
110     D3DLOCKED_RECT lockedRect;
111     RECT rectToLock = {x, y, x+1, y+1};
112
113     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8, 0, 0, TRUE, &surf, NULL);
114     if(FAILED(hr) || !surf )  /* This is not a test */
115     {
116         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
117         return 0xdeadbeef;
118     }
119
120     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
121     if(FAILED(hr))
122     {
123         trace("Can't get the render target, hr=%08x\n", hr);
124         ret = 0xdeadbeed;
125         goto out;
126     }
127
128     hr = IDirect3DDevice9_StretchRect(device, target, NULL, surf, NULL, D3DTEXF_POINT);
129     if(FAILED(hr))
130     {
131         trace("Can't read the render target data, hr=%08x\n", hr);
132         ret = 0xdeadbeec;
133         goto out;
134     }
135
136     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
137     if(FAILED(hr))
138     {
139         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
140         ret = 0xdeadbeeb;
141         goto out;
142     }
143
144     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
145      * really important for these tests
146      */
147     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
148     hr = IDirect3DSurface9_UnlockRect(surf);
149     if(FAILED(hr))
150     {
151         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
152     }
153
154 out:
155     if(target) IDirect3DSurface9_Release(target);
156     if(surf) IDirect3DSurface9_Release(surf);
157     return ret;
158 }
159
160 static IDirect3DDevice9 *init_d3d9(void)
161 {
162     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
163     IDirect3D9 *d3d9_ptr = 0;
164     IDirect3DDevice9 *device_ptr = 0;
165     D3DPRESENT_PARAMETERS present_parameters;
166     HRESULT hr;
167     D3DADAPTER_IDENTIFIER9 identifier;
168
169     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
170     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
171     if (!d3d9_create) return NULL;
172
173     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
174     if (!d3d9_ptr)
175     {
176         skip("could not create D3D9\n");
177         return NULL;
178     }
179
180     ZeroMemory(&present_parameters, sizeof(present_parameters));
181     present_parameters.Windowed = TRUE;
182     present_parameters.hDeviceWindow = create_window();
183     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
184     present_parameters.BackBufferWidth = 640;
185     present_parameters.BackBufferHeight = 480;
186     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
187     present_parameters.EnableAutoDepthStencil = TRUE;
188     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
189
190     memset(&identifier, 0, sizeof(identifier));
191     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
192     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
193     trace("Driver string: \"%s\"\n", identifier.Driver);
194     trace("Description string: \"%s\"\n", identifier.Description);
195     ok(identifier.Description[0] != '\0', "Empty driver description\n");
196     trace("Device name string: \"%s\"\n", identifier.DeviceName);
197     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
198     trace("Driver version %d.%d.%d.%d\n",
199           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
200           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
201
202     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
203     if(FAILED(hr)) {
204         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
205         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
206         if(FAILED(hr)) {
207             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
208         }
209     }
210     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
211
212     return device_ptr;
213 }
214
215 struct vertex
216 {
217     float x, y, z;
218     DWORD diffuse;
219 };
220
221 struct tvertex
222 {
223     float x, y, z, rhw;
224     DWORD diffuse;
225 };
226
227 struct nvertex
228 {
229     float x, y, z;
230     float nx, ny, nz;
231     DWORD diffuse;
232 };
233
234 static void lighting_test(IDirect3DDevice9 *device)
235 {
236     HRESULT hr;
237     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
238     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
239     DWORD color;
240     D3DMATERIAL9 material, old_material;
241     DWORD cop, carg;
242
243     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
244                       0.0f, 1.0f, 0.0f, 0.0f,
245                       0.0f, 0.0f, 1.0f, 0.0f,
246                       0.0f, 0.0f, 0.0f, 1.0f };
247
248     struct vertex unlitquad[] =
249     {
250         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
251         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
252         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
254     };
255     struct vertex litquad[] =
256     {
257         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
258         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
259         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
261     };
262     struct nvertex unlitnquad[] =
263     {
264         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
265         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268     };
269     struct nvertex litnquad[] =
270     {
271         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
272         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275     };
276     WORD Indices[] = {0, 1, 2, 2, 3, 0};
277
278     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
279     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
280
281     /* Setup some states that may cause issues */
282     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
283     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
284     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
285     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
286     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
287     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
292     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
293     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
294     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
295     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
300     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
301     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
302     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
303     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
304     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
305     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
306
307     hr = IDirect3DDevice9_SetFVF(device, 0);
308     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
309
310     hr = IDirect3DDevice9_SetFVF(device, fvf);
311     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
312
313     hr = IDirect3DDevice9_BeginScene(device);
314     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
315     if(hr == D3D_OK)
316     {
317         /* No lights are defined... That means, lit vertices should be entirely black */
318         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
322         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
323
324         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
328         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
329
330         hr = IDirect3DDevice9_SetFVF(device, nfvf);
331         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
332
333         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
334         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
335         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
336                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
337         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
338
339         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
340         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
341         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
342                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
343         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
344
345         IDirect3DDevice9_EndScene(device);
346         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
347     }
348
349     color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
350     ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
351     color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
352     ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
353     color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
354     ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
355     color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
356     ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
357
358     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359
360     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362     memset(&material, 0, sizeof(material));
363     material.Diffuse.r = 0.0;
364     material.Diffuse.g = 0.0;
365     material.Diffuse.b = 0.0;
366     material.Diffuse.a = 1.0;
367     material.Ambient.r = 0.0;
368     material.Ambient.g = 0.0;
369     material.Ambient.b = 0.0;
370     material.Ambient.a = 0.0;
371     material.Specular.r = 0.0;
372     material.Specular.g = 0.0;
373     material.Specular.b = 0.0;
374     material.Specular.a = 0.0;
375     material.Emissive.r = 0.0;
376     material.Emissive.g = 0.0;
377     material.Emissive.b = 0.0;
378     material.Emissive.a = 0.0;
379     material.Power = 0.0;
380     IDirect3DDevice9_SetMaterial(device, &material);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382
383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387
388     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396
397     hr = IDirect3DDevice9_BeginScene(device);
398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399     if(SUCCEEDED(hr)) {
400         struct vertex lighting_test[] = {
401             {-1.0,   -1.0,   0.1,    0x8000ff00},
402             { 1.0,   -1.0,   0.1,    0x80000000},
403             {-1.0,    1.0,   0.1,    0x8000ff00},
404             { 1.0,    1.0,   0.1,    0x80000000}
405         };
406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410
411         hr = IDirect3DDevice9_EndScene(device);
412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
413     }
414
415     color = getPixelColor(device, 320, 240);
416     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418
419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
431 }
432
433 static void clear_test(IDirect3DDevice9 *device)
434 {
435     /* Tests the correctness of clearing parameters */
436     HRESULT hr;
437     D3DRECT rect[2];
438     D3DRECT rect_negneg;
439     DWORD color;
440     D3DVIEWPORT9 old_vp, vp;
441     RECT scissor;
442     DWORD oldColorWrite;
443     BOOL invalid_clear_failed = FALSE;
444
445     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
447
448     /* Positive x, negative y */
449     rect[0].x1 = 0;
450     rect[0].y1 = 480;
451     rect[0].x2 = 320;
452     rect[0].y2 = 240;
453
454     /* Positive x, positive y */
455     rect[1].x1 = 0;
456     rect[1].y1 = 0;
457     rect[1].x2 = 320;
458     rect[1].y2 = 240;
459     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460      * returns D3D_OK, but ignores the rectangle silently
461      */
462     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465
466     /* negative x, negative y */
467     rect_negneg.x1 = 640;
468     rect_negneg.y1 = 240;
469     rect_negneg.x2 = 320;
470     rect_negneg.y2 = 0;
471     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
474
475     color = getPixelColor(device, 160, 360); /* lower left quad */
476     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477     color = getPixelColor(device, 160, 120); /* upper left quad */
478     if(invalid_clear_failed) {
479         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481     } else {
482         /* If the negative rectangle was dropped silently, the correct ones are cleared */
483         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
484     }
485     color = getPixelColor(device, 480, 360); /* lower right quad  */
486     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487     color = getPixelColor(device, 480, 120); /* upper right quad */
488     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
489
490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
491
492     /* Test how the viewport affects clears */
493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
497
498     vp.X = 160;
499     vp.Y = 120;
500     vp.Width = 160;
501     vp.Height = 120;
502     vp.MinZ = 0.0;
503     vp.MaxZ = 1.0;
504     hr = IDirect3DDevice9_SetViewport(device, &vp);
505     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     vp.X = 320;
510     vp.Y = 240;
511     vp.Width = 320;
512     vp.Height = 240;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     rect[0].x1 = 160;
518     rect[0].y1 = 120;
519     rect[0].x2 = 480;
520     rect[0].y2 = 360;
521     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523
524     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
526
527     color = getPixelColor(device, 158, 118);
528     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529     color = getPixelColor(device, 162, 118);
530     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531     color = getPixelColor(device, 158, 122);
532     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533     color = getPixelColor(device, 162, 122);
534     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
535
536     color = getPixelColor(device, 318, 238);
537     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538     color = getPixelColor(device, 322, 238);
539     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540     color = getPixelColor(device, 318, 242);
541     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542     color = getPixelColor(device, 322, 242);
543     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
544
545     color = getPixelColor(device, 478, 358);
546     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547     color = getPixelColor(device, 482, 358);
548     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549     color = getPixelColor(device, 478, 362);
550     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551     color = getPixelColor(device, 482, 362);
552     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
553
554     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
555
556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
558
559     scissor.left = 160;
560     scissor.right = 480;
561     scissor.top = 120;
562     scissor.bottom = 360;
563     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
567
568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
572
573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
575
576     color = getPixelColor(device, 158, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 162, 118);
579     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 158, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 162, 122);
583     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 158, 358);
586     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587     color = getPixelColor(device, 162, 358);
588     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589     color = getPixelColor(device, 158, 358);
590     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591     color = getPixelColor(device, 162, 362);
592     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
593
594     color = getPixelColor(device, 478, 118);
595     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596     color = getPixelColor(device, 478, 122);
597     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598     color = getPixelColor(device, 482, 122);
599     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600     color = getPixelColor(device, 482, 358);
601     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
602
603     color = getPixelColor(device, 478, 358);
604     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605     color = getPixelColor(device, 478, 362);
606     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607     color = getPixelColor(device, 482, 358);
608     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609     color = getPixelColor(device, 482, 362);
610     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
611
612     color = getPixelColor(device, 318, 238);
613     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614     color = getPixelColor(device, 318, 242);
615     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616     color = getPixelColor(device, 322, 238);
617     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618     color = getPixelColor(device, 322, 242);
619     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
620
621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622
623     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
627
628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Colorwriteenable does not affect the clear */
635     color = getPixelColor(device, 320, 240);
636     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
637
638     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639 }
640
641 static void color_fill_test(IDirect3DDevice9 *device)
642 {
643     HRESULT hr;
644     IDirect3DSurface9 *backbuffer = NULL;
645     IDirect3DSurface9 *rt_surface = NULL;
646     IDirect3DSurface9 *offscreen_surface = NULL;
647     DWORD fill_color, color;
648
649     /* Test ColorFill on a the backbuffer (should pass) */
650     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652     if(backbuffer)
653     {
654         fill_color = 0x112233;
655         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
656
657         color = getPixelColor(device, 0, 0);
658         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
659
660         IDirect3DSurface9_Release(backbuffer);
661     }
662
663     /* Test ColorFill on a render target surface (should pass) */
664     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666     if(rt_surface)
667     {
668         fill_color = 0x445566;
669         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
670
671         color = getPixelColorFromSurface(rt_surface, 0, 0);
672         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
673
674         IDirect3DSurface9_Release(rt_surface);
675     }
676
677     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681     if(offscreen_surface)
682     {
683         fill_color = 0x778899;
684         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
685
686         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
688
689         IDirect3DSurface9_Release(offscreen_surface);
690     }
691
692     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693     offscreen_surface = NULL;
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697     if(offscreen_surface)
698     {
699         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704 }
705
706 typedef struct {
707     float in[4];
708     DWORD out;
709 } test_data_t;
710
711 /*
712  *  c7      mova    ARGB            mov     ARGB
713  * -2.4     -2      0x00ffff00      -3      0x00ff0000
714  * -1.6     -2      0x00ffff00      -2      0x00ffff00
715  * -0.4      0      0x0000ffff      -1      0x0000ff00
716  *  0.4      0      0x0000ffff       0      0x0000ffff
717  *  1.6      2      0x00ff00ff       1      0x000000ff
718  *  2.4      2      0x00ff00ff       2      0x00ff00ff
719  */
720 static void test_mova(IDirect3DDevice9 *device)
721 {
722     static const DWORD mova_test[] = {
723         0xfffe0200,                                                             /* vs_2_0                       */
724         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
725         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
726         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
729         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
732         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
733         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
734         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
735         0x0000ffff                                                              /* END                          */
736     };
737     static const DWORD mov_test[] = {
738         0xfffe0101,                                                             /* vs_1_1                       */
739         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
740         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
741         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
744         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
747         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
748         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
749         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
750         0x0000ffff                                                              /* END                          */
751     };
752
753     static const test_data_t test_data[2][6] = {
754         {
755             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
761         },
762         {
763             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
769         }
770     };
771
772     static const float quad[][3] = {
773         {-1.0f, -1.0f, 0.0f},
774         {-1.0f,  1.0f, 0.0f},
775         { 1.0f, -1.0f, 0.0f},
776         { 1.0f,  1.0f, 0.0f},
777     };
778
779     static const D3DVERTEXELEMENT9 decl_elements[] = {
780         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781         D3DDECL_END()
782     };
783
784     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785     IDirect3DVertexShader9 *mova_shader = NULL;
786     IDirect3DVertexShader9 *mov_shader = NULL;
787     HRESULT hr;
788     UINT i, j;
789
790     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
798
799     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801     for(j = 0; j < 2; ++j)
802     {
803         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
804         {
805             DWORD color;
806
807             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
809
810             hr = IDirect3DDevice9_BeginScene(device);
811             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
812
813             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
815
816             hr = IDirect3DDevice9_EndScene(device);
817             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
818
819             color = getPixelColor(device, 320, 240);
820             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
822
823             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
828         }
829         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
831     }
832
833     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
835
836     IDirect3DVertexDeclaration9_Release(vertex_declaration);
837     IDirect3DVertexShader9_Release(mova_shader);
838     IDirect3DVertexShader9_Release(mov_shader);
839 }
840
841 struct sVertex {
842     float x, y, z;
843     DWORD diffuse;
844     DWORD specular;
845 };
846
847 struct sVertexT {
848     float x, y, z, rhw;
849     DWORD diffuse;
850     DWORD specular;
851 };
852
853 static void fog_test(IDirect3DDevice9 *device)
854 {
855     HRESULT hr;
856     D3DCOLOR color;
857     float start = 0.0f, end = 1.0f;
858     D3DCAPS9 caps;
859     int i;
860
861     /* Gets full z based fog with linear fog, no fog with specular color */
862     struct sVertex unstransformed_1[] = {
863         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
864         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
865         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
867     };
868     /* Ok, I am too lazy to deal with transform matrices */
869     struct sVertex unstransformed_2[] = {
870         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
871         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
872         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
874     };
875     /* Untransformed ones. Give them a different diffuse color to make the test look
876      * nicer. It also makes making sure that they are drawn correctly easier.
877      */
878     struct sVertexT transformed_1[] = {
879         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
880         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883     };
884     struct sVertexT transformed_2[] = {
885         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
886         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889     };
890     struct vertex rev_fog_quads[] = {
891        {-1.0,   -1.0,   0.1,    0x000000ff},
892        {-1.0,    0.0,   0.1,    0x000000ff},
893        { 0.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,   -1.0,   0.1,    0x000000ff},
895
896        { 0.0,   -1.0,   0.9,    0x000000ff},
897        { 0.0,    0.0,   0.9,    0x000000ff},
898        { 1.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,   -1.0,   0.9,    0x000000ff},
900
901        { 0.0,    0.0,   0.4,    0x000000ff},
902        { 0.0,    1.0,   0.4,    0x000000ff},
903        { 1.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    0.0,   0.4,    0x000000ff},
905
906        {-1.0,    0.0,   0.7,    0x000000ff},
907        {-1.0,    1.0,   0.7,    0x000000ff},
908        { 0.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    0.0,   0.7,    0x000000ff},
910     };
911     WORD Indices[] = {0, 1, 2, 2, 3, 0};
912
913     memset(&caps, 0, sizeof(caps));
914     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
918
919     /* Setup initial states: No lighting, fog on, fog color */
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
926
927     /* First test: Both table fog and vertex fog off */
928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
932
933     /* Start = 0, end = 1. Should be default, but set them */
934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
938
939     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
940     {
941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946                                                      sizeof(unstransformed_1[0]));
947         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
948
949         /* That makes it use the Z value */
950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952         /* Untransformed, vertex fog != none (or table fog != none):
953          * Use the Z value as input into the equation
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957                                                      sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959
960         /* transformed verts */
961         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966                                                      sizeof(transformed_1[0]));
967         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
968
969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972          * equation
973          */
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976                                                      sizeof(transformed_2[0]));
977         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
978
979         hr = IDirect3DDevice9_EndScene(device);
980         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
981     }
982     else
983     {
984         ok(FALSE, "BeginScene failed\n");
985     }
986
987     color = getPixelColor(device, 160, 360);
988     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989     color = getPixelColor(device, 160, 120);
990     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991     color = getPixelColor(device, 480, 120);
992     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
994     {
995         color = getPixelColor(device, 480, 360);
996         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
997     }
998     else
999     {
1000         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001          * The settings above result in no fogging with vertex fog
1002          */
1003         color = getPixelColor(device, 480, 120);
1004         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005         trace("Info: Table fog not supported by this device\n");
1006     }
1007     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1008
1009     /* Now test the special case fogstart == fogend */
1010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1012
1013     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1014     {
1015         start = 512;
1016         end = 512;
1017         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1021
1022         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1028
1029         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033          * color and has fixed fogstart and fogend.
1034          */
1035         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037                 sizeof(unstransformed_1[0]));
1038         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041                 sizeof(unstransformed_1[0]));
1042         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1043
1044         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049                 sizeof(transformed_1[0]));
1050         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1051
1052         hr = IDirect3DDevice9_EndScene(device);
1053         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1054     }
1055     else
1056     {
1057         ok(FALSE, "BeginScene failed\n");
1058     }
1059     color = getPixelColor(device, 160, 360);
1060     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061     color = getPixelColor(device, 160, 120);
1062     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063     color = getPixelColor(device, 480, 120);
1064     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066
1067     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068      * but without shaders it seems to work everywhere
1069      */
1070     end = 0.2;
1071     start = 0.8;
1072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1078
1079     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081      * so skip this for now
1082      */
1083     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084         const char *mode = (i ? "table" : "vertex");
1085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091         hr = IDirect3DDevice9_BeginScene(device);
1092         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093         if(SUCCEEDED(hr)) {
1094             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1095                                 4,  5,  6,  6,  7, 4,
1096                                 8,  9, 10, 10, 11, 8,
1097                             12, 13, 14, 14, 15, 12};
1098
1099             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101                     sizeof(rev_fog_quads[0]));
1102             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1103
1104             hr = IDirect3DDevice9_EndScene(device);
1105             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1106         }
1107         color = getPixelColor(device, 160, 360);
1108         ok(color_match(color, 0x0000ff00, 1),
1109                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1110
1111         color = getPixelColor(device, 160, 120);
1112         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1114
1115         color = getPixelColor(device, 480, 120);
1116         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1118
1119         color = getPixelColor(device, 480, 360);
1120         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1121
1122         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1123
1124         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126             break;
1127         }
1128     }
1129     /* Turn off the fog master switch to avoid confusing other tests */
1130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132     start = 0.0;
1133     end = 1.0;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 }
1143
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146  * regardless of the actual addressing mode set. */
1147 static void test_cube_wrap(IDirect3DDevice9 *device)
1148 {
1149     static const float quad[][6] = {
1150         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1151         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1152         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1153         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1154     };
1155
1156     static const D3DVERTEXELEMENT9 decl_elements[] = {
1157         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1158         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1159         D3DDECL_END()
1160     };
1161
1162     static const struct {
1163         D3DTEXTUREADDRESS mode;
1164         const char *name;
1165     } address_modes[] = {
1166         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1167         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1168         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1169         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1170         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1171     };
1172
1173     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1174     IDirect3DCubeTexture9 *texture = NULL;
1175     IDirect3DSurface9 *surface = NULL;
1176     D3DLOCKED_RECT locked_rect;
1177     HRESULT hr;
1178     UINT x;
1179     INT y, face;
1180
1181     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1182     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1183     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1184     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1185
1186     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1187             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1188     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1189
1190     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1191     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1192
1193     for (y = 0; y < 128; ++y)
1194     {
1195         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1196         for (x = 0; x < 64; ++x)
1197         {
1198             *ptr++ = 0xffff0000;
1199         }
1200         for (x = 64; x < 128; ++x)
1201         {
1202             *ptr++ = 0xff0000ff;
1203         }
1204     }
1205
1206     hr = IDirect3DSurface9_UnlockRect(surface);
1207     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1208
1209     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1210             D3DPOOL_DEFAULT, &texture, NULL);
1211     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1212
1213     /* Create cube faces */
1214     for (face = 0; face < 6; ++face)
1215     {
1216         IDirect3DSurface9 *face_surface = NULL;
1217
1218         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1219         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1220
1221         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1222         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1223
1224         IDirect3DSurface9_Release(face_surface);
1225     }
1226
1227     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1228     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1229
1230     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1231     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1232     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1233     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1234     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1235     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1236
1237     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1238     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1239
1240     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1241     {
1242         DWORD color;
1243
1244         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1245         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1246         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1247         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1248
1249         hr = IDirect3DDevice9_BeginScene(device);
1250         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1251
1252         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1253         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1254
1255         hr = IDirect3DDevice9_EndScene(device);
1256         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1257
1258         /* Due to the nature of this test, we sample essentially at the edge
1259          * between two faces. Because of this it's undefined from which face
1260          * the driver will sample. Fortunately that's not important for this
1261          * test, since all we care about is that it doesn't sample from the
1262          * other side of the surface or from the border. */
1263         color = getPixelColor(device, 320, 240);
1264         ok(color == 0x00ff0000 || color == 0x000000ff,
1265                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1266                 color, address_modes[x].name);
1267
1268         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1269         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1270
1271         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1272         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1273     }
1274
1275     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1276     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1277
1278     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1279     IDirect3DCubeTexture9_Release(texture);
1280     IDirect3DSurface9_Release(surface);
1281 }
1282
1283 static void offscreen_test(IDirect3DDevice9 *device)
1284 {
1285     HRESULT hr;
1286     IDirect3DTexture9 *offscreenTexture = NULL;
1287     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1288     DWORD color;
1289
1290     static const float quad[][5] = {
1291         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1292         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1293         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1294         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1295     };
1296
1297     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1298     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1299
1300     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1301     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1302     if(!offscreenTexture) {
1303         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1304         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1305         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1306         if(!offscreenTexture) {
1307             skip("Cannot create an offscreen render target\n");
1308             goto out;
1309         }
1310     }
1311
1312     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1313     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1314     if(!backbuffer) {
1315         goto out;
1316     }
1317
1318     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1319     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1320     if(!offscreen) {
1321         goto out;
1322     }
1323
1324     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1325     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1326
1327     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1328     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1329     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1330     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1331     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1332     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1333     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1334     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1335     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1336     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1337
1338     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1339         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1340         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1341         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1342         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1343
1344         /* Draw without textures - Should result in a white quad */
1345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1346         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1347
1348         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1349         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1350         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1351         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1352
1353         /* This time with the texture */
1354         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1355         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1356
1357         IDirect3DDevice9_EndScene(device);
1358     }
1359
1360     /* Center quad - should be white */
1361     color = getPixelColor(device, 320, 240);
1362     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1363     /* Some quad in the cleared part of the texture */
1364     color = getPixelColor(device, 170, 240);
1365     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1366     /* Part of the originally cleared back buffer */
1367     color = getPixelColor(device, 10, 10);
1368     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1369     if(0) {
1370         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1371          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1372          * the offscreen rendering mode this test would succeed or fail
1373          */
1374         color = getPixelColor(device, 10, 470);
1375         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1376     }
1377
1378     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1379
1380 out:
1381     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1382     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1383
1384     /* restore things */
1385     if(backbuffer) {
1386         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1387         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1388         IDirect3DSurface9_Release(backbuffer);
1389     }
1390     if(offscreenTexture) {
1391         IDirect3DTexture9_Release(offscreenTexture);
1392     }
1393     if(offscreen) {
1394         IDirect3DSurface9_Release(offscreen);
1395     }
1396 }
1397
1398 /* This test tests fog in combination with shaders.
1399  * What's tested: linear fog (vertex and table) with pixel shader
1400  *                linear table fog with non foggy vertex shader
1401  *                vertex fog with foggy vertex shader, non-linear
1402  *                fog with shader, non-linear fog with foggy shader,
1403  *                linear table fog with foggy shader
1404  */
1405 static void fog_with_shader_test(IDirect3DDevice9 *device)
1406 {
1407     HRESULT hr;
1408     DWORD color;
1409     union {
1410         float f;
1411         DWORD i;
1412     } start, end;
1413     unsigned int i, j;
1414
1415     /* basic vertex shader without fog computation ("non foggy") */
1416     static const DWORD vertex_shader_code1[] = {
1417         0xfffe0101,                                                             /* vs_1_1                       */
1418         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1419         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1420         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1421         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1422         0x0000ffff
1423     };
1424     /* basic vertex shader with reversed fog computation ("foggy") */
1425     static const DWORD vertex_shader_code2[] = {
1426         0xfffe0101,                                                             /* vs_1_1                        */
1427         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1428         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1429         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1430         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1431         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1432         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1433         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1434         0x0000ffff
1435     };
1436     /* basic pixel shader */
1437     static const DWORD pixel_shader_code[] = {
1438         0xffff0101,                                                             /* ps_1_1     */
1439         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1440         0x0000ffff
1441     };
1442
1443     static struct vertex quad[] = {
1444         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1445         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1446         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1447         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1448     };
1449
1450     static const D3DVERTEXELEMENT9 decl_elements[] = {
1451         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1452         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1453         D3DDECL_END()
1454     };
1455
1456     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1457     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1458     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1459
1460     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1461     static const struct test_data_t {
1462         int vshader;
1463         int pshader;
1464         D3DFOGMODE vfog;
1465         D3DFOGMODE tfog;
1466         unsigned int color[11];
1467     } test_data[] = {
1468         /* only pixel shader: */
1469         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1470         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1471         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1472         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1473         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1474         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1475         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1476         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1477         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1478         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1479         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1480         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1481         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1482         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1483         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1484
1485         /* vertex shader */
1486         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1487         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1488          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1489         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1490         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1491         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1492         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1493         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1494         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1495
1496         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1497         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1498         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1499         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1500         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1501         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1502
1503         /* vertex shader and pixel shader */
1504         /* The next 4 tests would read the fog coord output, but it isn't available.
1505          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1506          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1507          * These tests should be disabled if some other hardware behaves differently
1508          */
1509         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1510         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1511         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1512         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1513         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1514         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1515         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1516         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1517         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1518         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1519         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1520         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1521
1522         /* These use the Z coordinate with linear table fog */
1523         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1524         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1525         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1526         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1527         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1528         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1529         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1530         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1531         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1532         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1533         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1534         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1535
1536         /* Non-linear table fog without fog coord */
1537         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1538         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1539         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1540         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1541         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1542         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1543
1544 #if 0  /* FIXME: these fail on GeForce 8500 */
1545         /* foggy vertex shader */
1546         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1547         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1548          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1549         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1550         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1551          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1552         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1553         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1554          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1555         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1556         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1557          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1558 #endif
1559
1560         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1561          * all using the fixed fog-coord linear fog
1562          */
1563         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1564         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1565          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1566         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1567         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1568          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1569         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1570         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1571          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1572         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1573         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1574          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1575
1576         /* These use table fog. Here the shader-provided fog coordinate is
1577          * ignored and the z coordinate used instead
1578          */
1579         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1580         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1581         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1582         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1583         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1584         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1585         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1586         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1587         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1588     };
1589
1590     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1591     start.f=0.1f;
1592     end.f=0.9f;
1593
1594     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1595     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1596     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1597     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1598     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1599     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1600     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1601     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1602
1603     /* Setup initial states: No lighting, fog on, fog color */
1604     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1605     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1606     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1607     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1608     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1609     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1610     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1611     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1612
1613     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1614     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1615     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1616     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1617
1618     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1619     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1620     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1621     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1622     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1623
1624     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1625     {
1626         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1627         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1628         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1629         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1630         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1631         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1632         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1633         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1634
1635         for(j=0; j < 11; j++)
1636         {
1637             /* Don't use the whole zrange to prevent rounding errors */
1638             quad[0].z = 0.001f + (float)j / 10.02f;
1639             quad[1].z = 0.001f + (float)j / 10.02f;
1640             quad[2].z = 0.001f + (float)j / 10.02f;
1641             quad[3].z = 0.001f + (float)j / 10.02f;
1642
1643             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1644             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1645
1646             hr = IDirect3DDevice9_BeginScene(device);
1647             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1648
1649             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1650             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1651
1652             hr = IDirect3DDevice9_EndScene(device);
1653             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1654
1655             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1656             color = getPixelColor(device, 128, 240);
1657             ok(color_match(color, test_data[i].color[j], 13),
1658                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1659                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1660
1661             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1662         }
1663     }
1664
1665     /* reset states */
1666     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1667     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1668     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1669     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1670     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1671     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1672     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1673     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1674
1675     IDirect3DVertexShader9_Release(vertex_shader[1]);
1676     IDirect3DVertexShader9_Release(vertex_shader[2]);
1677     IDirect3DPixelShader9_Release(pixel_shader[1]);
1678     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1679 }
1680
1681 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1682     unsigned int i, x, y;
1683     HRESULT hr;
1684     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1685     D3DLOCKED_RECT locked_rect;
1686
1687     /* Generate the textures */
1688     for(i=0; i<2; i++)
1689     {
1690         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1691                                             D3DPOOL_MANAGED, &texture[i], NULL);
1692         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1693
1694         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1695         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1696         for (y = 0; y < 128; ++y)
1697         {
1698             if(i)
1699             { /* Set up black texture with 2x2 texel white spot in the middle */
1700                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1701                 for (x = 0; x < 128; ++x)
1702                 {
1703                     if(y>62 && y<66 && x>62 && x<66)
1704                         *ptr++ = 0xffffffff;
1705                     else
1706                         *ptr++ = 0xff000000;
1707                 }
1708             }
1709             else
1710             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1711                * (if multiplied with bumpenvmat)
1712               */
1713                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1714                 for (x = 0; x < 128; ++x)
1715                 {
1716                     if(abs(x-64)>abs(y-64))
1717                     {
1718                         if(x < 64)
1719                             *ptr++ = 0xc000;
1720                         else
1721                             *ptr++ = 0x4000;
1722                     }
1723                     else
1724                     {
1725                         if(y < 64)
1726                             *ptr++ = 0x0040;
1727                         else
1728                             *ptr++ = 0x00c0;
1729                     }
1730                 }
1731             }
1732         }
1733         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1734         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1735
1736         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1737         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1738
1739         /* Disable texture filtering */
1740         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1741         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1742         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1743         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1744
1745         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1746         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1747         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1748         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1749     }
1750 }
1751
1752 /* test the behavior of the texbem instruction
1753  * with normal 2D and projective 2D textures
1754  */
1755 static void texbem_test(IDirect3DDevice9 *device)
1756 {
1757     HRESULT hr;
1758     DWORD color;
1759     int i;
1760
1761     static const DWORD pixel_shader_code[] = {
1762         0xffff0101,                         /* ps_1_1*/
1763         0x00000042, 0xb00f0000,             /* tex t0*/
1764         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1765         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1766         0x0000ffff
1767     };
1768     static const DWORD double_texbem_code[] =  {
1769         0xffff0103,                                         /* ps_1_3           */
1770         0x00000042, 0xb00f0000,                             /* tex t0           */
1771         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1772         0x00000042, 0xb00f0002,                             /* tex t2           */
1773         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1774         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1775         0x0000ffff                                          /* end              */
1776     };
1777
1778
1779     static const float quad[][7] = {
1780         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1781         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1782         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1783         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1784     };
1785     static const float quad_proj[][9] = {
1786         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1787         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1788         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1789         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1790     };
1791
1792     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1793         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1794         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1795         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1796         D3DDECL_END()
1797     },{
1798         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1799         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1800         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1801         D3DDECL_END()
1802     } };
1803
1804     /* use asymmetric matrix to test loading */
1805     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1806
1807     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1808     IDirect3DPixelShader9       *pixel_shader       = NULL;
1809     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1810     D3DLOCKED_RECT locked_rect;
1811
1812     generate_bumpmap_textures(device);
1813
1814     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1815     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1816     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1817     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1818     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1819
1820     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1821     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1822
1823     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1824     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1825
1826     for(i=0; i<2; i++)
1827     {
1828         if(i)
1829         {
1830             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1831             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1832         }
1833
1834         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1835         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1836         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1837         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1838
1839         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1840         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1841         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1842         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1843
1844         hr = IDirect3DDevice9_BeginScene(device);
1845         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1846
1847         if(!i)
1848             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1849         else
1850             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1851         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1852
1853         hr = IDirect3DDevice9_EndScene(device);
1854         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1855
1856         color = getPixelColor(device, 320-32, 240);
1857         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1858         color = getPixelColor(device, 320+32, 240);
1859         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1860         color = getPixelColor(device, 320, 240-32);
1861         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1862         color = getPixelColor(device, 320, 240+32);
1863         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1864
1865         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1866         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1867
1868         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1869         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1870         IDirect3DPixelShader9_Release(pixel_shader);
1871
1872         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1873         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1874         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1875     }
1876
1877     /* clean up */
1878     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1879     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1880
1881     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1882     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1883
1884     for(i=0; i<2; i++)
1885     {
1886         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1887         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1888         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1889         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1890         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1891         IDirect3DTexture9_Release(texture);
1892     }
1893
1894     /* Test double texbem */
1895     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1896     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1897     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1898     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1899     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1900     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1901     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1902     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1903
1904     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1905     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1906     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1907     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1908
1909     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1910     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1911
1912     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1913     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1914     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1915     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1916     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1917     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1918
1919     {
1920         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1921 #define tex  0x00ff0000
1922 #define tex1 0x0000ff00
1923 #define origin 0x000000ff
1924         static const DWORD pixel_data[] = {
1925             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1926             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1927             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1928             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1929             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1930             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1931             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1932             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1933         };
1934 #undef tex1
1935 #undef tex2
1936 #undef origin
1937
1938         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1939         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1940         for(i = 0; i < 8; i++) {
1941             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1942         }
1943         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1944         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1945     }
1946
1947     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1948     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1949     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1950     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1951     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1952     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1953     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1954     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1955     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1956     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1957     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1958     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1959
1960     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1961     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1962     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1963     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1964     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1965     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1966     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1967     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1968     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1969     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1970
1971     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1972     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1973     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1974     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1975     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1977     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1979     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1981
1982     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1983     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1984     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1985     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1986     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1987     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1988     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1989     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1990     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1998
1999     hr = IDirect3DDevice9_BeginScene(device);
2000     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2001     if(SUCCEEDED(hr)) {
2002         static const float double_quad[] = {
2003             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2004              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2005             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2006              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2007         };
2008
2009         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2010         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2011         hr = IDirect3DDevice9_EndScene(device);
2012         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2013     }
2014     color = getPixelColor(device, 320, 240);
2015     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2016
2017     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2018     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2019     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2020     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2021     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2022     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2023     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2025     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2026     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2027
2028     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2029     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2030
2031     IDirect3DPixelShader9_Release(pixel_shader);
2032     IDirect3DTexture9_Release(texture);
2033     IDirect3DTexture9_Release(texture1);
2034     IDirect3DTexture9_Release(texture2);
2035 }
2036
2037 static void z_range_test(IDirect3DDevice9 *device)
2038 {
2039     const struct vertex quad[] =
2040     {
2041         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2042         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2043         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2044         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2045     };
2046     const struct vertex quad2[] =
2047     {
2048         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2049         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2050         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2051         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2052     };
2053
2054     const struct tvertex quad3[] =
2055     {
2056         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2057         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2058         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2059         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2060     };
2061     const struct tvertex quad4[] =
2062     {
2063         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2064         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2065         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2066         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2067     };
2068     HRESULT hr;
2069     DWORD color;
2070     IDirect3DVertexShader9 *shader;
2071     IDirect3DVertexDeclaration9 *decl;
2072     D3DCAPS9 caps;
2073     const DWORD shader_code[] = {
2074         0xfffe0101,                                     /* vs_1_1           */
2075         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2076         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2077         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2078         0x0000ffff                                      /* end              */
2079     };
2080     static const D3DVERTEXELEMENT9 decl_elements[] = {
2081         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2082         D3DDECL_END()
2083     };
2084     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2085      * then call Present. Then clear the color buffer to make sure it has some defined content
2086      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2087      * by the depth value.
2088      */
2089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2090     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2091     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2092     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2093     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2094     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2095
2096     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2097     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2098     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2099     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2100     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2101     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2102     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2103     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2104     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2105     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2106
2107     hr = IDirect3DDevice9_BeginScene(device);
2108     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2109     if(hr == D3D_OK)
2110     {
2111         /* Test the untransformed vertex path */
2112         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2113         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2114         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2115         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2116         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2117         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2118
2119         /* Test the transformed vertex path */
2120         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2121         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2122
2123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2124         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2125         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2126         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2127         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2128         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2129
2130         hr = IDirect3DDevice9_EndScene(device);
2131         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2132     }
2133
2134     /* Do not test the exact corner pixels, but go pretty close to them */
2135
2136     /* Clipped because z > 1.0 */
2137     color = getPixelColor(device, 28, 238);
2138     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2139     color = getPixelColor(device, 28, 241);
2140     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2141
2142     /* Not clipped, > z buffer clear value(0.75) */
2143     color = getPixelColor(device, 31, 238);
2144     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2145     color = getPixelColor(device, 31, 241);
2146     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2147     color = getPixelColor(device, 100, 238);
2148     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2149     color = getPixelColor(device, 100, 241);
2150     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2151
2152     /* Not clipped, < z buffer clear value */
2153     color = getPixelColor(device, 104, 238);
2154     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2155     color = getPixelColor(device, 104, 241);
2156     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2157     color = getPixelColor(device, 318, 238);
2158     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2159     color = getPixelColor(device, 318, 241);
2160     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2161
2162     /* Clipped because z < 0.0 */
2163     color = getPixelColor(device, 321, 238);
2164     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2165     color = getPixelColor(device, 321, 241);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167
2168     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2169     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2170
2171     /* Test the shader path */
2172     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2173     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2174         skip("Vertex shaders not supported\n");
2175         goto out;
2176     }
2177     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2178     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2179     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2180     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2181
2182     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2183
2184     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2185     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2186     IDirect3DDevice9_SetVertexShader(device, shader);
2187     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2188
2189     hr = IDirect3DDevice9_BeginScene(device);
2190     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2191     if(hr == D3D_OK)
2192     {
2193         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2194         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2195         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2196         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2197         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2198         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2199         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2200         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2201         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2202         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2203
2204         hr = IDirect3DDevice9_EndScene(device);
2205         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2206     }
2207
2208     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2209     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2210     IDirect3DDevice9_SetVertexShader(device, NULL);
2211     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2212
2213     IDirect3DVertexDeclaration9_Release(decl);
2214     IDirect3DVertexShader9_Release(shader);
2215
2216     /* Z < 1.0 */
2217     color = getPixelColor(device, 28, 238);
2218     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2219
2220     /* 1.0 < z < 0.75 */
2221     color = getPixelColor(device, 31, 238);
2222     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2223     color = getPixelColor(device, 100, 238);
2224     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2225
2226     /* 0.75 < z < 0.0 */
2227     color = getPixelColor(device, 104, 238);
2228     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2229     color = getPixelColor(device, 318, 238);
2230     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2231
2232     /* 0.0 < z */
2233     color = getPixelColor(device, 321, 238);
2234     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2235
2236     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2237     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2238
2239     out:
2240     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2241     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2242     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2243     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2244     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2245     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2246 }
2247
2248 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2249 {
2250     D3DSURFACE_DESC desc;
2251     D3DLOCKED_RECT l;
2252     HRESULT hr;
2253     unsigned int x, y;
2254     DWORD *mem;
2255
2256     memset(&desc, 0, sizeof(desc));
2257     memset(&l, 0, sizeof(l));
2258     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2259     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2260     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2261     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2262     if(FAILED(hr)) return;
2263
2264     for(y = 0; y < desc.Height; y++)
2265     {
2266         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2267         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2268         {
2269             mem[x] = color;
2270         }
2271     }
2272     hr = IDirect3DSurface9_UnlockRect(surface);
2273     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2274 }
2275
2276 /* This tests a variety of possible StretchRect() situations */
2277 static void stretchrect_test(IDirect3DDevice9 *device)
2278 {
2279     HRESULT hr;
2280     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2281     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2282     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2283     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2284     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2285     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2286     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2287     IDirect3DSurface9 *orig_rt = NULL;
2288     IDirect3DSurface9 *backbuffer = NULL;
2289     DWORD color;
2290
2291     RECT src_rect64 = {0, 0, 64, 64};
2292     RECT src_rect64_flipy = {0, 64, 64, 0};
2293     RECT dst_rect64 = {0, 0, 64, 64};
2294     RECT dst_rect64_flipy = {0, 64, 64, 0};
2295
2296     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2297     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2298     if(!orig_rt) {
2299         goto out;
2300     }
2301
2302     /* Create our temporary surfaces in system memory */
2303     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2304     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2305     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2306     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2307
2308     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2309     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2310     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2311     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2312     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2313     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2314     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2315
2316     /* Create render target surfaces */
2317     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2318     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2319     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2320     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2321     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2322     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2323     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2324     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2325
2326     /* Create render target textures */
2327     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2328     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2329     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2330     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2331     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2332     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2334     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2335     if (tex_rt32) {
2336         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2337         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2338     }
2339     if (tex_rt64) {
2340         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2341         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2342     }
2343     if (tex_rt_dest64) {
2344         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2345         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2346     }
2347     if (tex_rt_dest64) {
2348         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2349         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2350     }
2351
2352     /* Create regular textures in D3DPOOL_DEFAULT */
2353     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2354     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2355     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2356     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2358     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2359     if (tex32) {
2360         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2361         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2362     }
2363     if (tex64) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_dest64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371
2372     /*********************************************************************
2373      * Tests for when the source parameter is an offscreen plain surface *
2374      *********************************************************************/
2375
2376     /* Fill the offscreen 64x64 surface with green */
2377     if (surf_offscreen64)
2378         fill_surface(surf_offscreen64, 0xff00ff00);
2379
2380     /* offscreenplain ==> offscreenplain, same size */
2381     if(surf_offscreen64 && surf_offscreen_dest64) {
2382         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2383         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2384
2385         if (hr == D3D_OK) {
2386             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2387             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2388         }
2389
2390         /* Blit without scaling */
2391         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2392         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2393
2394         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2395         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2396         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2397
2398         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2399         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2400         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2401     }
2402
2403     /* offscreenplain ==> rendertarget texture, same size */
2404     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2405         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2406         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2407
2408         /* We can't lock rendertarget textures, so copy to our temp surface first */
2409         if (hr == D3D_OK) {
2410             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2411             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2412         }
2413
2414         if (hr == D3D_OK) {
2415             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2416             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2417         }
2418
2419         /* Blit without scaling */
2420         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2421         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2422
2423         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2424         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2425         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2426
2427         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2428         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2429         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2430     }
2431
2432     /* offscreenplain ==> rendertarget surface, same size */
2433     if(surf_offscreen64 && surf_rt_dest64) {
2434         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2435         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2436
2437         if (hr == D3D_OK) {
2438             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2439             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2440         }
2441
2442         /* Blit without scaling */
2443         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2444         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2445
2446         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2447         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2448         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2449
2450         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2451         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2452         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2453     }
2454
2455     /* offscreenplain ==> texture, same size (should fail) */
2456     if(surf_offscreen64 && surf_tex_dest64) {
2457         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2458         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2459     }
2460
2461     /* Fill the smaller offscreen surface with red */
2462     fill_surface(surf_offscreen32, 0xffff0000);
2463
2464     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2465     if(surf_offscreen32 && surf_offscreen64) {
2466         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2467         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2468     }
2469
2470     /* offscreenplain ==> rendertarget texture, scaling */
2471     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2472         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2473         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2474
2475         /* We can't lock rendertarget textures, so copy to our temp surface first */
2476         if (hr == D3D_OK) {
2477             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2478             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2479         }
2480
2481         if (hr == D3D_OK) {
2482             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2483             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2484         }
2485     }
2486
2487     /* offscreenplain ==> rendertarget surface, scaling */
2488     if(surf_offscreen32 && surf_rt_dest64) {
2489         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2490         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2491
2492         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2493         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2494     }
2495
2496     /* offscreenplain ==> texture, scaling (should fail) */
2497     if(surf_offscreen32 && surf_tex_dest64) {
2498         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2499         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2500     }
2501
2502     /************************************************************
2503      * Tests for when the source parameter is a regular texture *
2504      ************************************************************/
2505
2506     /* Fill the surface of the regular texture with blue */
2507     if (surf_tex64 && surf_temp64) {
2508         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2509         fill_surface(surf_temp64, 0xff0000ff);
2510         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2511         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2512     }
2513
2514     /* texture ==> offscreenplain, same size */
2515     if(surf_tex64 && surf_offscreen64) {
2516         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2517         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2518     }
2519
2520     /* texture ==> rendertarget texture, same size */
2521     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2522         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2523         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2524
2525         /* We can't lock rendertarget textures, so copy to our temp surface first */
2526         if (hr == D3D_OK) {
2527             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2528             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2529         }
2530
2531         if (hr == D3D_OK) {
2532             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2533             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2534         }
2535
2536         /* Blit without scaling */
2537         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2538         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2539
2540         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2541         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2542         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2543
2544         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2545         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2546         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2547     }
2548
2549     /* texture ==> rendertarget surface, same size */
2550     if(surf_tex64 && surf_rt_dest64) {
2551         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2552         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2553
2554         if (hr == D3D_OK) {
2555             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2556             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2557         }
2558
2559         /* Blit without scaling */
2560         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2561         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2562
2563         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2564         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2565         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2566
2567         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2568         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2569         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2570     }
2571
2572     /* texture ==> texture, same size (should fail) */
2573     if(surf_tex64 && surf_tex_dest64) {
2574         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2575         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2576     }
2577
2578     /* Fill the surface of the smaller regular texture with red */
2579     if (surf_tex32 && surf_temp32) {
2580         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2581         fill_surface(surf_temp32, 0xffff0000);
2582         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2583         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2584     }
2585
2586     /* texture ==> offscreenplain, scaling (should fail) */
2587     if(surf_tex32 && surf_offscreen64) {
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2589         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2590     }
2591
2592     /* texture ==> rendertarget texture, scaling */
2593     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2594         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2595         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2596
2597         /* We can't lock rendertarget textures, so copy to our temp surface first */
2598         if (hr == D3D_OK) {
2599             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2600             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2601         }
2602
2603         if (hr == D3D_OK) {
2604             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2605             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2606         }
2607     }
2608
2609     /* texture ==> rendertarget surface, scaling */
2610     if(surf_tex32 && surf_rt_dest64) {
2611         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2612         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2613
2614         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2615         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2616     }
2617
2618     /* texture ==> texture, scaling (should fail) */
2619     if(surf_tex32 && surf_tex_dest64) {
2620         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2621         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2622     }
2623
2624     /*****************************************************************
2625      * Tests for when the source parameter is a rendertarget texture *
2626      *****************************************************************/
2627
2628     /* Fill the surface of the rendertarget texture with white */
2629     if (surf_tex_rt64 && surf_temp64) {
2630         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2631         fill_surface(surf_temp64, 0xffffffff);
2632         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2633         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2634     }
2635
2636     /* rendertarget texture ==> offscreenplain, same size */
2637     if(surf_tex_rt64 && surf_offscreen64) {
2638         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2639         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2640     }
2641
2642     /* rendertarget texture ==> rendertarget texture, same size */
2643     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2644         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2645         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2646
2647         /* We can't lock rendertarget textures, so copy to our temp surface first */
2648         if (hr == D3D_OK) {
2649             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2650             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2651         }
2652
2653         if (hr == D3D_OK) {
2654             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2655             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2656         }
2657
2658         /* Blit without scaling */
2659         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2660         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2661
2662         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2663         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2664         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2665
2666         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2667         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2668         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2669     }
2670
2671     /* rendertarget texture ==> rendertarget surface, same size */
2672     if(surf_tex_rt64 && surf_rt_dest64) {
2673         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2674         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2675
2676         if (hr == D3D_OK) {
2677             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2678             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2679         }
2680
2681         /* Blit without scaling */
2682         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2683         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2684
2685         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2686         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2687         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2688
2689         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2690         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2691         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2692     }
2693
2694     /* rendertarget texture ==> texture, same size (should fail) */
2695     if(surf_tex_rt64 && surf_tex_dest64) {
2696         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2697         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2698     }
2699
2700     /* Fill the surface of the smaller rendertarget texture with red */
2701     if (surf_tex_rt32 && surf_temp32) {
2702         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2703         fill_surface(surf_temp32, 0xffff0000);
2704         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2705         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2706     }
2707
2708     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2709     if(surf_tex_rt32 && surf_offscreen64) {
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2711         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2712     }
2713
2714     /* rendertarget texture ==> rendertarget texture, scaling */
2715     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2716         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2717         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2718
2719         /* We can't lock rendertarget textures, so copy to our temp surface first */
2720         if (hr == D3D_OK) {
2721             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2722             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2723         }
2724
2725         if (hr == D3D_OK) {
2726             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2727             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2728         }
2729     }
2730
2731     /* rendertarget texture ==> rendertarget surface, scaling */
2732     if(surf_tex_rt32 && surf_rt_dest64) {
2733         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2734         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2735
2736         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2737         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2738     }
2739
2740     /* rendertarget texture ==> texture, scaling (should fail) */
2741     if(surf_tex_rt32 && surf_tex_dest64) {
2742         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2743         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2744     }
2745
2746     /*****************************************************************
2747      * Tests for when the source parameter is a rendertarget surface *
2748      *****************************************************************/
2749
2750     /* Fill the surface of the rendertarget surface with black */
2751     if (surf_rt64)
2752         fill_surface(surf_rt64, 0xff000000);
2753
2754     /* rendertarget texture ==> offscreenplain, same size */
2755     if(surf_rt64 && surf_offscreen64) {
2756         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2757         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2758     }
2759
2760     /* rendertarget surface ==> rendertarget texture, same size */
2761     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2762         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2763         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764
2765         /* We can't lock rendertarget textures, so copy to our temp surface first */
2766         if (hr == D3D_OK) {
2767             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2768             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2769         }
2770
2771         if (hr == D3D_OK) {
2772             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2773             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2774         }
2775
2776         /* Blit without scaling */
2777         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2778         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2779
2780         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2781         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2782         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2783
2784         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2785         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2786         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2787     }
2788
2789     /* rendertarget surface ==> rendertarget surface, same size */
2790     if(surf_rt64 && surf_rt_dest64) {
2791         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2792         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2793
2794         if (hr == D3D_OK) {
2795             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2796             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2797         }
2798
2799         /* Blit without scaling */
2800         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2801         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2802
2803         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2804         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2805         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2806
2807         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2808         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2809         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2810     }
2811
2812     /* rendertarget surface ==> texture, same size (should fail) */
2813     if(surf_rt64 && surf_tex_dest64) {
2814         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2815         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2816     }
2817
2818     /* Fill the surface of the smaller rendertarget texture with red */
2819     if (surf_rt32)
2820         fill_surface(surf_rt32, 0xffff0000);
2821
2822     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2823     if(surf_rt32 && surf_offscreen64) {
2824         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2825         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2826     }
2827
2828     /* rendertarget surface ==> rendertarget texture, scaling */
2829     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2830         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2831         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2832
2833         /* We can't lock rendertarget textures, so copy to our temp surface first */
2834         if (hr == D3D_OK) {
2835             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2836             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2837         }
2838
2839         if (hr == D3D_OK) {
2840             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2841             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2842         }
2843     }
2844
2845     /* rendertarget surface ==> rendertarget surface, scaling */
2846     if(surf_rt32 && surf_rt_dest64) {
2847         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2848         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2849
2850         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2851         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2852     }
2853
2854     /* rendertarget surface ==> texture, scaling (should fail) */
2855     if(surf_rt32 && surf_tex_dest64) {
2856         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2857         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2858     }
2859
2860     /* backbuffer ==> surface tests (no scaling) */
2861     if(backbuffer && surf_tex_rt_dest640_480)
2862     {
2863         RECT src_rect = {0, 0, 640, 480};
2864         RECT src_rect_flipy = {0, 480, 640, 0};
2865         RECT dst_rect = {0, 0, 640, 480};
2866         RECT dst_rect_flipy = {0, 480, 640, 0};
2867
2868         /* Blit with NULL rectangles */
2869         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2870         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2871
2872         /* Blit without scaling */
2873         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2874         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2875
2876         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2877         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2878         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2879
2880         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2881         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2882         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2883     }
2884
2885     /* TODO: Test format conversions */
2886
2887
2888 out:
2889     /* Clean up */
2890     if (backbuffer)
2891         IDirect3DSurface9_Release(backbuffer);
2892     if (surf_rt32)
2893         IDirect3DSurface9_Release(surf_rt32);
2894     if (surf_rt64)
2895         IDirect3DSurface9_Release(surf_rt64);
2896     if (surf_rt_dest64)
2897         IDirect3DSurface9_Release(surf_rt_dest64);
2898     if (surf_temp32)
2899         IDirect3DSurface9_Release(surf_temp32);
2900     if (surf_temp64)
2901         IDirect3DSurface9_Release(surf_temp64);
2902     if (surf_offscreen32)
2903         IDirect3DSurface9_Release(surf_offscreen32);
2904     if (surf_offscreen64)
2905         IDirect3DSurface9_Release(surf_offscreen64);
2906     if (surf_offscreen_dest64)
2907         IDirect3DSurface9_Release(surf_offscreen_dest64);
2908
2909     if (tex_rt32) {
2910         if (surf_tex_rt32)
2911             IDirect3DSurface9_Release(surf_tex_rt32);
2912         IDirect3DTexture9_Release(tex_rt32);
2913     }
2914     if (tex_rt64) {
2915         if (surf_tex_rt64)
2916             IDirect3DSurface9_Release(surf_tex_rt64);
2917         IDirect3DTexture9_Release(tex_rt64);
2918     }
2919     if (tex_rt_dest64) {
2920         if (surf_tex_rt_dest64)
2921             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2922         IDirect3DTexture9_Release(tex_rt_dest64);
2923     }
2924     if (tex_rt_dest640_480) {
2925         if (surf_tex_rt_dest640_480)
2926             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2927         IDirect3DTexture9_Release(tex_rt_dest640_480);
2928     }
2929     if (tex32) {
2930         if (surf_tex32)
2931             IDirect3DSurface9_Release(surf_tex32);
2932         IDirect3DTexture9_Release(tex32);
2933     }
2934     if (tex64) {
2935         if (surf_tex64)
2936             IDirect3DSurface9_Release(surf_tex64);
2937         IDirect3DTexture9_Release(tex64);
2938     }
2939     if (tex_dest64) {
2940         if (surf_tex_dest64)
2941             IDirect3DSurface9_Release(surf_tex_dest64);
2942         IDirect3DTexture9_Release(tex_dest64);
2943     }
2944
2945     if (orig_rt) {
2946         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2947         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2948         IDirect3DSurface9_Release(orig_rt);
2949     }
2950 }
2951
2952 static void maxmip_test(IDirect3DDevice9 *device)
2953 {
2954     IDirect3DTexture9 *texture = NULL;
2955     IDirect3DSurface9 *surface = NULL;
2956     HRESULT hr;
2957     DWORD color;
2958     const float quads[] = {
2959         -1.0,   -1.0,   0.0,    0.0,    0.0,
2960         -1.0,    0.0,   0.0,    0.0,    1.0,
2961          0.0,   -1.0,   0.0,    1.0,    0.0,
2962          0.0,    0.0,   0.0,    1.0,    1.0,
2963
2964          0.0,   -1.0,   0.0,    0.0,    0.0,
2965          0.0,    0.0,   0.0,    0.0,    1.0,
2966          1.0,   -1.0,   0.0,    1.0,    0.0,
2967          1.0,    0.0,   0.0,    1.0,    1.0,
2968
2969          0.0,    0.0,   0.0,    0.0,    0.0,
2970          0.0,    1.0,   0.0,    0.0,    1.0,
2971          1.0,    0.0,   0.0,    1.0,    0.0,
2972          1.0,    1.0,   0.0,    1.0,    1.0,
2973
2974         -1.0,    0.0,   0.0,    0.0,    0.0,
2975         -1.0,    1.0,   0.0,    0.0,    1.0,
2976          0.0,    0.0,   0.0,    1.0,    0.0,
2977          0.0,    1.0,   0.0,    1.0,    1.0,
2978     };
2979
2980     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2981     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2982
2983     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2984                                         &texture, NULL);
2985     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2986     if(!texture)
2987     {
2988         skip("Failed to create test texture\n");
2989         return;
2990     }
2991
2992     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2993     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2994     fill_surface(surface, 0xffff0000);
2995     IDirect3DSurface9_Release(surface);
2996     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2997     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2998     fill_surface(surface, 0xff00ff00);
2999     IDirect3DSurface9_Release(surface);
3000     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3001     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3002     fill_surface(surface, 0xff0000ff);
3003     IDirect3DSurface9_Release(surface);
3004
3005     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3006     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3007     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3009
3010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3012
3013     hr = IDirect3DDevice9_BeginScene(device);
3014     if(SUCCEEDED(hr))
3015     {
3016         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3017         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3018         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3019         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3020
3021         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3022         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3023         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3024         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3025
3026         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3027         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3028         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3029         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3030
3031         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3032         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3033         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3034         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3035         hr = IDirect3DDevice9_EndScene(device);
3036         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3037     }
3038
3039     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3040     color = getPixelColor(device, 160, 360);
3041     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3042     color = getPixelColor(device, 160, 120);
3043     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3044     color = getPixelColor(device, 480, 120);
3045     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3046     color = getPixelColor(device, 480, 360);
3047     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3048     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3049     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3050
3051     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3052     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3053
3054     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3055     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056
3057     hr = IDirect3DDevice9_BeginScene(device);
3058     if(SUCCEEDED(hr))
3059     {
3060         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3061         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3062         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3063         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3064
3065         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3066         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3067         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3068         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3069
3070         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3071         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3072         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3073         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3074
3075         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3076         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3077         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3078         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3079         hr = IDirect3DDevice9_EndScene(device);
3080         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3081     }
3082
3083     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3084      * samples from the highest level in the texture(level 2)
3085      */
3086     color = getPixelColor(device, 160, 360);
3087     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3088     color = getPixelColor(device, 160, 120);
3089     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3090     color = getPixelColor(device, 480, 120);
3091     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3092     color = getPixelColor(device, 480, 360);
3093     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3094     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3095     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3096
3097     hr = IDirect3DDevice9_BeginScene(device);
3098     if(SUCCEEDED(hr))
3099     {
3100         DWORD ret;
3101
3102         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3106         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3107         ret = IDirect3DTexture9_SetLOD(texture, 1);
3108         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3109         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3110         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3111
3112         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3113         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3114         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3115         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3116         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3117         ret = IDirect3DTexture9_SetLOD(texture, 2);
3118         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3119         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3120         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3121
3122         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3123         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3124         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3125         ret = IDirect3DTexture9_SetLOD(texture, 1);
3126         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3127         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3128         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3129
3130         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3134         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135         ret = IDirect3DTexture9_SetLOD(texture, 1);
3136         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139         hr = IDirect3DDevice9_EndScene(device);
3140     }
3141
3142     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3143      * samples from the highest level in the texture(level 2)
3144      */
3145     color = getPixelColor(device, 160, 360);
3146     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3147     color = getPixelColor(device, 160, 120);
3148     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3149     color = getPixelColor(device, 480, 120);
3150     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3151     color = getPixelColor(device, 480, 360);
3152     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3153     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3154     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3155
3156     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3157     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3158     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3159     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3160     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3161     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3162     IDirect3DTexture9_Release(texture);
3163 }
3164
3165 static void release_buffer_test(IDirect3DDevice9 *device)
3166 {
3167     IDirect3DVertexBuffer9 *vb = NULL;
3168     IDirect3DIndexBuffer9 *ib = NULL;
3169     HRESULT hr;
3170     BYTE *data;
3171     LONG ref;
3172
3173     static const struct vertex quad[] = {
3174         {-1.0,      -1.0,       0.1,        0xffff0000},
3175         {-1.0,       1.0,       0.1,        0xffff0000},
3176         { 1.0,       1.0,       0.1,        0xffff0000},
3177
3178         {-1.0,      -1.0,       0.1,        0xff00ff00},
3179         {-1.0,       1.0,       0.1,        0xff00ff00},
3180         { 1.0,       1.0,       0.1,        0xff00ff00}
3181     };
3182     short indices[] = {3, 4, 5};
3183
3184     /* Index and vertex buffers should always be creatable */
3185     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3186                                               D3DPOOL_MANAGED, &vb, NULL);
3187     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3188     if(!vb) {
3189         skip("Failed to create a vertex buffer\n");
3190         return;
3191     }
3192     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3193     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3194     if(!ib) {
3195         skip("Failed to create an index buffer\n");
3196         return;
3197     }
3198
3199     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3200     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3201     memcpy(data, quad, sizeof(quad));
3202     hr = IDirect3DVertexBuffer9_Unlock(vb);
3203     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3204
3205     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3206     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3207     memcpy(data, indices, sizeof(indices));
3208     hr = IDirect3DIndexBuffer9_Unlock(ib);
3209     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3210
3211     hr = IDirect3DDevice9_SetIndices(device, ib);
3212     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3213     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3214     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3215     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3216     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3217
3218     /* Now destroy the bound index buffer and draw again */
3219     ref = IDirect3DIndexBuffer9_Release(ib);
3220     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3221
3222     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3223     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3224
3225     hr = IDirect3DDevice9_BeginScene(device);
3226     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3227     if(SUCCEEDED(hr))
3228     {
3229         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3230          * making assumptions about the indices or vertices
3231          */
3232         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3233         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3234         hr = IDirect3DDevice9_EndScene(device);
3235         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3236     }
3237
3238     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3239     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3240
3241     hr = IDirect3DDevice9_SetIndices(device, NULL);
3242     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3243     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3244     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3245
3246     /* Index buffer was already destroyed as part of the test */
3247     IDirect3DVertexBuffer9_Release(vb);
3248 }
3249
3250 static void float_texture_test(IDirect3DDevice9 *device)
3251 {
3252     IDirect3D9 *d3d = NULL;
3253     HRESULT hr;
3254     IDirect3DTexture9 *texture = NULL;
3255     D3DLOCKED_RECT lr;
3256     float *data;
3257     DWORD color;
3258     float quad[] = {
3259         -1.0,      -1.0,       0.1,     0.0,    0.0,
3260         -1.0,       1.0,       0.1,     0.0,    1.0,
3261          1.0,      -1.0,       0.1,     1.0,    0.0,
3262          1.0,       1.0,       0.1,     1.0,    1.0,
3263     };
3264
3265     memset(&lr, 0, sizeof(lr));
3266     IDirect3DDevice9_GetDirect3D(device, &d3d);
3267     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3268                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3269         skip("D3DFMT_R32F textures not supported\n");
3270         goto out;
3271     }
3272
3273     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3274                                         D3DPOOL_MANAGED, &texture, NULL);
3275     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3276     if(!texture) {
3277         skip("Failed to create R32F texture\n");
3278         goto out;
3279     }
3280
3281     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3282     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3283     data = lr.pBits;
3284     *data = 0.0;
3285     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3286     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3287
3288     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3289     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3290
3291     hr = IDirect3DDevice9_BeginScene(device);
3292     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3293     if(SUCCEEDED(hr))
3294     {
3295         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3296         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3297
3298         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3299         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3300
3301         hr = IDirect3DDevice9_EndScene(device);
3302         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3303     }
3304     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3305     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3306
3307     color = getPixelColor(device, 240, 320);
3308     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3309
3310     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3311     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3312
3313 out:
3314     if(texture) IDirect3DTexture9_Release(texture);
3315     IDirect3D9_Release(d3d);
3316 }
3317
3318 static void g16r16_texture_test(IDirect3DDevice9 *device)
3319 {
3320     IDirect3D9 *d3d = NULL;
3321     HRESULT hr;
3322     IDirect3DTexture9 *texture = NULL;
3323     D3DLOCKED_RECT lr;
3324     DWORD *data;
3325     DWORD color;
3326     float quad[] = {
3327        -1.0,      -1.0,       0.1,     0.0,    0.0,
3328        -1.0,       1.0,       0.1,     0.0,    1.0,
3329         1.0,      -1.0,       0.1,     1.0,    0.0,
3330         1.0,       1.0,       0.1,     1.0,    1.0,
3331     };
3332
3333     memset(&lr, 0, sizeof(lr));
3334     IDirect3DDevice9_GetDirect3D(device, &d3d);
3335     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3336        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3337            skip("D3DFMT_G16R16 textures not supported\n");
3338            goto out;
3339     }
3340
3341     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3342                                         D3DPOOL_MANAGED, &texture, NULL);
3343     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3344     if(!texture) {
3345         skip("Failed to create D3DFMT_G16R16 texture\n");
3346         goto out;
3347     }
3348
3349     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3350     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3351     data = lr.pBits;
3352     *data = 0x0f00f000;
3353     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3354     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3355
3356     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3357     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3358
3359     hr = IDirect3DDevice9_BeginScene(device);
3360     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3361     if(SUCCEEDED(hr))
3362     {
3363         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3364         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3365
3366         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3367         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3368
3369         hr = IDirect3DDevice9_EndScene(device);
3370         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3371     }
3372     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3373     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3374
3375     color = getPixelColor(device, 240, 320);
3376     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3377        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3378
3379     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3380     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3381
3382 out:
3383     if(texture) IDirect3DTexture9_Release(texture);
3384     IDirect3D9_Release(d3d);
3385 }
3386
3387 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3388 {
3389     HRESULT hr;
3390     IDirect3D9 *d3d;
3391     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3392     D3DCAPS9 caps;
3393     IDirect3DTexture9 *texture = NULL;
3394     IDirect3DVolumeTexture9 *volume = NULL;
3395     unsigned int x, y, z;
3396     D3DLOCKED_RECT lr;
3397     D3DLOCKED_BOX lb;
3398     DWORD color;
3399     UINT w, h;
3400     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3401     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3402                            0.0, 1.0, 0.0, 0.0,
3403                            0.0, 0.0, 1.0, 0.0,
3404                            0.0, 0.0, 0.0, 1.0};
3405     static const D3DVERTEXELEMENT9 decl_elements[] = {
3406         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3407         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3408         D3DDECL_END()
3409     };
3410     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3411         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3412         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3413         D3DDECL_END()
3414     };
3415     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3416         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3417         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3418         D3DDECL_END()
3419     };
3420     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3421                                                  0x00, 0xff, 0x00, 0x00,
3422                                                  0x00, 0x00, 0x00, 0x00,
3423                                                  0x00, 0x00, 0x00, 0x00};
3424
3425     memset(&lr, 0, sizeof(lr));
3426     memset(&lb, 0, sizeof(lb));
3427     IDirect3DDevice9_GetDirect3D(device, &d3d);
3428     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3429                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3430         fmt = D3DFMT_A16B16G16R16;
3431     }
3432     IDirect3D9_Release(d3d);
3433
3434     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3435     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3436     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3437     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3438     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3439     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3440     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3441     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3442     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3443     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3444     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3445     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3446     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3447     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3448     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3449     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3450     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3451     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3452     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3453     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3454     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3455     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3456     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3457     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3458
3459     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3460     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3461     w = min(1024, caps.MaxTextureWidth);
3462     h = min(1024, caps.MaxTextureHeight);
3463     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3464                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3466     if(!texture) {
3467         skip("Failed to create the test texture\n");
3468         return;
3469     }
3470
3471     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3472      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3473      * 1.0 in red and green for the x and y coords
3474      */
3475     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3476     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3477     for(y = 0; y < h; y++) {
3478         for(x = 0; x < w; x++) {
3479             double r_f = (double) y / (double) h;
3480             double g_f = (double) x / (double) w;
3481             if(fmt == D3DFMT_A16B16G16R16) {
3482                 unsigned short r, g;
3483                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3484                 r = (unsigned short) (r_f * 65536.0);
3485                 g = (unsigned short) (g_f * 65536.0);
3486                 dst[0] = r;
3487                 dst[1] = g;
3488                 dst[2] = 0;
3489                 dst[3] = 65535;
3490             } else {
3491                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3492                 unsigned char r = (unsigned char) (r_f * 255.0);
3493                 unsigned char g = (unsigned char) (g_f * 255.0);
3494                 dst[0] = 0;
3495                 dst[1] = g;
3496                 dst[2] = r;
3497                 dst[3] = 255;
3498             }
3499         }
3500     }
3501     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3502     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3503     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3504     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3505
3506     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3507     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3508     hr = IDirect3DDevice9_BeginScene(device);
3509     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3510     if(SUCCEEDED(hr))
3511     {
3512         float quad1[] = {
3513             -1.0,      -1.0,       0.1,     1.0,    1.0,
3514             -1.0,       0.0,       0.1,     1.0,    1.0,
3515              0.0,      -1.0,       0.1,     1.0,    1.0,
3516              0.0,       0.0,       0.1,     1.0,    1.0,
3517         };
3518         float quad2[] = {
3519             -1.0,       0.0,       0.1,     1.0,    1.0,
3520             -1.0,       1.0,       0.1,     1.0,    1.0,
3521              0.0,       0.0,       0.1,     1.0,    1.0,
3522              0.0,       1.0,       0.1,     1.0,    1.0,
3523         };
3524         float quad3[] = {
3525              0.0,       0.0,       0.1,     0.5,    0.5,
3526              0.0,       1.0,       0.1,     0.5,    0.5,
3527              1.0,       0.0,       0.1,     0.5,    0.5,
3528              1.0,       1.0,       0.1,     0.5,    0.5,
3529         };
3530         float quad4[] = {
3531              320,       480,       0.1,     1.0,    0.0,    1.0,
3532              320,       240,       0.1,     1.0,    0.0,    1.0,
3533              640,       480,       0.1,     1.0,    0.0,    1.0,
3534              640,       240,       0.1,     1.0,    0.0,    1.0,
3535         };
3536         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3537                           0.0, 0.0, 0.0, 0.0,
3538                           0.0, 0.0, 0.0, 0.0,
3539                           0.0, 0.0, 0.0, 0.0};
3540
3541         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3542         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3543         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3544         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3545         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3546
3547         /* What happens with transforms enabled? */
3548         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3549         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3550         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3551         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3552
3553         /* What happens if 4 coords are used, but only 2 given ?*/
3554         mat[8] = 1.0;
3555         mat[13] = 1.0;
3556         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3557         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3558         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3559         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3560         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3561         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3562
3563         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3564          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3565          * due to the coords in the vertices. (turns out red, indeed)
3566          */
3567         memset(mat, 0, sizeof(mat));
3568         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3569         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3570         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3571         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3572         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3573         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3574         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3575         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3576
3577         hr = IDirect3DDevice9_EndScene(device);
3578         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3579     }
3580     color = getPixelColor(device, 160, 360);
3581     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3582     color = getPixelColor(device, 160, 120);
3583     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3584     color = getPixelColor(device, 480, 120);
3585     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3586     color = getPixelColor(device, 480, 360);
3587     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3588     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3589     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3590
3591     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3592     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3593
3594     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3595     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3596     hr = IDirect3DDevice9_BeginScene(device);
3597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3598     if(SUCCEEDED(hr))
3599     {
3600         float quad1[] = {
3601             -1.0,      -1.0,       0.1,     0.8,    0.2,
3602             -1.0,       0.0,       0.1,     0.8,    0.2,
3603              0.0,      -1.0,       0.1,     0.8,    0.2,
3604              0.0,       0.0,       0.1,     0.8,    0.2,
3605         };
3606         float quad2[] = {
3607             -1.0,       0.0,       0.1,     0.5,    1.0,
3608             -1.0,       1.0,       0.1,     0.5,    1.0,
3609              0.0,       0.0,       0.1,     0.5,    1.0,
3610              0.0,       1.0,       0.1,     0.5,    1.0,
3611         };
3612         float quad3[] = {
3613              0.0,       0.0,       0.1,     0.5,    1.0,
3614              0.0,       1.0,       0.1,     0.5,    1.0,
3615              1.0,       0.0,       0.1,     0.5,    1.0,
3616              1.0,       1.0,       0.1,     0.5,    1.0,
3617         };
3618         float quad4[] = {
3619              0.0,      -1.0,       0.1,     0.8,    0.2,
3620              0.0,       0.0,       0.1,     0.8,    0.2,
3621              1.0,      -1.0,       0.1,     0.8,    0.2,
3622              1.0,       0.0,       0.1,     0.8,    0.2,
3623         };
3624         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3625                           0.0, 0.0, 0.0, 0.0,
3626                           0.0, 1.0, 0.0, 0.0,
3627                           0.0, 0.0, 0.0, 0.0};
3628
3629         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3630          */
3631         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3632         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3633         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3634         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3635
3636         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3637         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3638
3639         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3640          * it behaves like COUNT2 because normal textures require 2 coords
3641          */
3642         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3643         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3644         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3645         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3646
3647         /* Just to be sure, the same as quad2 above */
3648         memset(mat, 0, sizeof(mat));
3649         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3650         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3651         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3652         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3653         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3654         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3655
3656         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3657          * used? And what happens to the first?
3658          */
3659         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3660         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3661         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3662         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3663
3664         hr = IDirect3DDevice9_EndScene(device);
3665         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3666     }
3667     color = getPixelColor(device, 160, 360);
3668     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3669     color = getPixelColor(device, 160, 120);
3670     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3671     color = getPixelColor(device, 480, 120);
3672     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3673        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3674     color = getPixelColor(device, 480, 360);
3675     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3676        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3677     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3678     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3679
3680     IDirect3DTexture9_Release(texture);
3681
3682     /* Test projected textures, without any fancy matrices */
3683     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3684     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3685     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3686     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3687     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3688     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3689     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3690     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3691
3692     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3693     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3694     for(x = 0; x < 4; x++) {
3695         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3696     }
3697     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3698     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3699     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3700     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3701
3702     hr = IDirect3DDevice9_BeginScene(device);
3703     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3704     if(SUCCEEDED(hr))
3705     {
3706         const float proj_quads[] = {
3707            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3708             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3709            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3710             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3711            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3712             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3713            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3714             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3715         };
3716
3717         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3718         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3720         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3721
3722         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3723         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3724         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3725         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3726
3727         hr = IDirect3DDevice9_EndScene(device);
3728         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3729     }
3730
3731     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3732     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3733     IDirect3DTexture9_Release(texture);
3734
3735     color = getPixelColor(device, 158, 118);
3736     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3737     color = getPixelColor(device, 162, 118);
3738     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3739     color = getPixelColor(device, 158, 122);
3740     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3741     color = getPixelColor(device, 162, 122);
3742     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3743
3744     color = getPixelColor(device, 158, 178);
3745     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3746     color = getPixelColor(device, 162, 178);
3747     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3748     color = getPixelColor(device, 158, 182);
3749     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3750     color = getPixelColor(device, 162, 182);
3751     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3752
3753     color = getPixelColor(device, 318, 118);
3754     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3755     color = getPixelColor(device, 322, 118);
3756     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3757     color = getPixelColor(device, 318, 122);
3758     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3759     color = getPixelColor(device, 322, 122);
3760     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3761
3762     color = getPixelColor(device, 318, 178);
3763     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3764     color = getPixelColor(device, 322, 178);
3765     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3766     color = getPixelColor(device, 318, 182);
3767     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3768     color = getPixelColor(device, 322, 182);
3769     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3770
3771     color = getPixelColor(device, 238, 298);
3772     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3773     color = getPixelColor(device, 242, 298);
3774     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3775     color = getPixelColor(device, 238, 302);
3776     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3777     color = getPixelColor(device, 242, 302);
3778     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3779
3780     color = getPixelColor(device, 238, 388);
3781     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3782     color = getPixelColor(device, 242, 388);
3783     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3784     color = getPixelColor(device, 238, 392);
3785     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3786     color = getPixelColor(device, 242, 392);
3787     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3788
3789     color = getPixelColor(device, 478, 298);
3790     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3791     color = getPixelColor(device, 482, 298);
3792     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3793     color = getPixelColor(device, 478, 302);
3794     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3795     color = getPixelColor(device, 482, 302);
3796     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3797
3798     color = getPixelColor(device, 478, 388);
3799     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3800     color = getPixelColor(device, 482, 388);
3801     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3802     color = getPixelColor(device, 478, 392);
3803     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3804     color = getPixelColor(device, 482, 392);
3805     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3806
3807     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3808     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3809
3810     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3811     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3812     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3813      * Thus watch out if sampling from texels between 0 and 1.
3814      */
3815     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3816     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3817        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3818     if(!volume) {
3819         skip("Failed to create a volume texture\n");
3820         goto out;
3821     }
3822
3823     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3824     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3825     for(z = 0; z < 32; z++) {
3826         for(y = 0; y < 32; y++) {
3827             for(x = 0; x < 32; x++) {
3828                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3829                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3830                 float r_f = (float) x / 31.0;
3831                 float g_f = (float) y / 31.0;
3832                 float b_f = (float) z / 31.0;
3833
3834                 if(fmt == D3DFMT_A16B16G16R16) {
3835                     unsigned short *mem_s = mem;
3836                     mem_s[0]  = r_f * 65535.0;
3837                     mem_s[1]  = g_f * 65535.0;
3838                     mem_s[2]  = b_f * 65535.0;
3839                     mem_s[3]  = 65535;
3840                 } else {
3841                     unsigned char *mem_c = mem;
3842                     mem_c[0]  = b_f * 255.0;
3843                     mem_c[1]  = g_f * 255.0;
3844                     mem_c[2]  = r_f * 255.0;
3845                     mem_c[3]  = 255;
3846                 }
3847             }
3848         }
3849     }
3850     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3851     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3852
3853     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3854     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3855
3856     hr = IDirect3DDevice9_BeginScene(device);
3857     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3858     if(SUCCEEDED(hr))
3859     {
3860         float quad1[] = {
3861             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3862             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3863              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3864              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3865         };
3866         float quad2[] = {
3867             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3868             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3869              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3870              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3871         };
3872         float quad3[] = {
3873              0.0,       0.0,       0.1,     0.0,    0.0,
3874              0.0,       1.0,       0.1,     0.0,    0.0,
3875              1.0,       0.0,       0.1,     0.0,    0.0,
3876              1.0,       1.0,       0.1,     0.0,    0.0
3877         };
3878         float quad4[] = {
3879              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3880              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3881              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3882              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3883         };
3884         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3885                          0.0, 0.0, 1.0, 0.0,
3886                          0.0, 1.0, 0.0, 0.0,
3887                          0.0, 0.0, 0.0, 1.0};
3888         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3889         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3890
3891         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3892          * values
3893          */
3894         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3895         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3896         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3897         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3898         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3899         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3900
3901         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3902          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3903          * otherwise the w will be missing(blue).
3904          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3905          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3906          */
3907         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3908         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3909         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3910         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3911
3912         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3913         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3914         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3915         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3916         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3917         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3918         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3919         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3920         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3921
3922         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3923          * disable. ATI extends it up to the amount of values needed for the volume texture
3924          */
3925         memset(mat, 0, sizeof(mat));
3926         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3927         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3928         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3929         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3930         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3931         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3932         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3933         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3934
3935         hr = IDirect3DDevice9_EndScene(device);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3937     }
3938
3939     color = getPixelColor(device, 160, 360);
3940     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3941     color = getPixelColor(device, 160, 120);
3942     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3943        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3944     color = getPixelColor(device, 480, 120);
3945     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3946     color = getPixelColor(device, 480, 360);
3947     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3948
3949     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3950     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3951
3952     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3953     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3954     hr = IDirect3DDevice9_BeginScene(device);
3955     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3956     if(SUCCEEDED(hr))
3957     {
3958         float quad1[] = {
3959             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3960             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3961              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3962              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3963         };
3964         float quad2[] = {
3965             -1.0,       0.0,       0.1,
3966             -1.0,       1.0,       0.1,
3967              0.0,       0.0,       0.1,
3968              0.0,       1.0,       0.1,
3969         };
3970         float quad3[] = {
3971              0.0,       0.0,       0.1,     1.0,
3972              0.0,       1.0,       0.1,     1.0,
3973              1.0,       0.0,       0.1,     1.0,
3974              1.0,       1.0,       0.1,     1.0
3975         };
3976         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3977                            0.0, 0.0, 0.0, 0.0,
3978                            0.0, 0.0, 0.0, 0.0,
3979                            0.0, 1.0, 0.0, 0.0};
3980         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3981                            1.0, 0.0, 0.0, 0.0,
3982                            0.0, 1.0, 0.0, 0.0,
3983                            0.0, 0.0, 1.0, 0.0};
3984         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3985         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3986
3987         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3988          */
3989         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3990         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3991         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3992         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3993         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3994         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3995
3996         /* None passed */
3997         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3998         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3999         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4000         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4001         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4002         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4003
4004         /* 4 used, 1 passed */
4005         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4006         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4007         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4008         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4009         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4010         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4011
4012         hr = IDirect3DDevice9_EndScene(device);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4014     }
4015     color = getPixelColor(device, 160, 360);
4016     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4017     color = getPixelColor(device, 160, 120);
4018     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4019     color = getPixelColor(device, 480, 120);
4020     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4021     /* Quad4: unused */
4022
4023     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4024     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4025
4026     IDirect3DVolumeTexture9_Release(volume);
4027
4028     out:
4029     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4030     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4031     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4032     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4033     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4035     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4036     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4037     IDirect3DVertexDeclaration9_Release(decl);
4038     IDirect3DVertexDeclaration9_Release(decl2);
4039     IDirect3DVertexDeclaration9_Release(decl3);
4040 }
4041
4042 static void texdepth_test(IDirect3DDevice9 *device)
4043 {
4044     IDirect3DPixelShader9 *shader;
4045     HRESULT hr;
4046     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4047     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4048     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4049     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4050     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4051     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4052     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4053     DWORD shader_code[] = {
4054         0xffff0104,                                                                 /* ps_1_4               */
4055         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4056         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4057         0x0000fffd,                                                                 /* phase                */
4058         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4059         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4060         0x0000ffff                                                                  /* end                  */
4061     };
4062     DWORD color;
4063     float vertex[] = {
4064        -1.0,   -1.0,    0.0,
4065         1.0,   -1.0,    1.0,
4066        -1.0,    1.0,    0.0,
4067         1.0,    1.0,    1.0
4068     };
4069
4070     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4071     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4072
4073     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4074     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4076     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4078     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4079     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4080     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4081     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4082     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4083
4084     /* Fill the depth buffer with a gradient */
4085     hr = IDirect3DDevice9_BeginScene(device);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4087     if(SUCCEEDED(hr))
4088     {
4089         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4090         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4091         hr = IDirect3DDevice9_EndScene(device);
4092         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4093     }
4094
4095     /* Now perform the actual tests. Same geometry, but with the shader */
4096     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4097     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4098     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4099     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4100     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4101     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4102
4103     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4105     hr = IDirect3DDevice9_BeginScene(device);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4107     if(SUCCEEDED(hr))
4108     {
4109         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4110         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4111
4112         hr = IDirect3DDevice9_EndScene(device);
4113         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4114     }
4115
4116     color = getPixelColor(device, 158, 240);
4117     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4118     color = getPixelColor(device, 162, 240);
4119     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4120
4121     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4122     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4123
4124     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4125     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4126
4127     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4128     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4129     hr = IDirect3DDevice9_BeginScene(device);
4130     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4131     if(SUCCEEDED(hr))
4132     {
4133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4134         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4135
4136         hr = IDirect3DDevice9_EndScene(device);
4137         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4138     }
4139
4140     color = getPixelColor(device, 318, 240);
4141     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4142     color = getPixelColor(device, 322, 240);
4143     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4144
4145     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4147
4148     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4149     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4150
4151     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4153     hr = IDirect3DDevice9_BeginScene(device);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4155     if(SUCCEEDED(hr))
4156     {
4157         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4158         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4159
4160         hr = IDirect3DDevice9_EndScene(device);
4161         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4162     }
4163
4164     color = getPixelColor(device, 1, 240);
4165     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4166
4167     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4168     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4169
4170     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4171     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4172
4173     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4175     hr = IDirect3DDevice9_BeginScene(device);
4176     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4177     if(SUCCEEDED(hr))
4178     {
4179         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4180         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4181
4182         hr = IDirect3DDevice9_EndScene(device);
4183         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4184     }
4185     color = getPixelColor(device, 318, 240);
4186     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4187     color = getPixelColor(device, 322, 240);
4188     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4189
4190     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4191     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4192
4193     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4194     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4195
4196     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4197     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4198     hr = IDirect3DDevice9_BeginScene(device);
4199     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4200     if(SUCCEEDED(hr))
4201     {
4202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4203         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4204
4205         hr = IDirect3DDevice9_EndScene(device);
4206         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4207     }
4208
4209     color = getPixelColor(device, 1, 240);
4210     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4211
4212     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4213     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4214
4215     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4216     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4217
4218     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4219     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4220     hr = IDirect3DDevice9_BeginScene(device);
4221     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4222     if(SUCCEEDED(hr))
4223     {
4224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4225         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4226
4227         hr = IDirect3DDevice9_EndScene(device);
4228         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4229     }
4230
4231     color = getPixelColor(device, 638, 240);
4232     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4233
4234     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4235     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4236
4237     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4238     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4239
4240     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4241     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4242     hr = IDirect3DDevice9_BeginScene(device);
4243     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4244     if(SUCCEEDED(hr))
4245     {
4246         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4247         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4248
4249         hr = IDirect3DDevice9_EndScene(device);
4250         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4251     }
4252
4253     color = getPixelColor(device, 638, 240);
4254     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4255
4256     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4257     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4258
4259     /* Cleanup */
4260     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4262     IDirect3DPixelShader9_Release(shader);
4263
4264     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4265     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4266     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4268 }
4269
4270 static void texkill_test(IDirect3DDevice9 *device)
4271 {
4272     IDirect3DPixelShader9 *shader;
4273     HRESULT hr;
4274     DWORD color;
4275
4276     const float vertex[] = {
4277     /*                          bottom  top    right    left */
4278         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4279          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4280         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4281          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4282     };
4283
4284     DWORD shader_code_11[] = {
4285     0xffff0101,                                                             /* ps_1_1                     */
4286     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4287     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4288     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4289     0x0000ffff                                                              /* end                        */
4290     };
4291     DWORD shader_code_20[] = {
4292     0xffff0200,                                                             /* ps_2_0                     */
4293     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4294     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4295     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4296     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4297     0x0000ffff                                                              /* end                        */
4298     };
4299
4300     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4301     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4302     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4303     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4304
4305     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4306     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4307     hr = IDirect3DDevice9_BeginScene(device);
4308     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4309     if(SUCCEEDED(hr))
4310     {
4311         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4312         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4313         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4314         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4315         hr = IDirect3DDevice9_EndScene(device);
4316         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4317     }
4318     color = getPixelColor(device, 63, 46);
4319     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4320     color = getPixelColor(device, 66, 46);
4321     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4322     color = getPixelColor(device, 63, 49);
4323     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4324     color = getPixelColor(device, 66, 49);
4325     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4326
4327     color = getPixelColor(device, 578, 46);
4328     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4329     color = getPixelColor(device, 575, 46);
4330     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4331     color = getPixelColor(device, 578, 49);
4332     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4333     color = getPixelColor(device, 575, 49);
4334     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4335
4336     color = getPixelColor(device, 63, 430);
4337     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4338     color = getPixelColor(device, 63, 433);
4339     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4340     color = getPixelColor(device, 66, 433);
4341     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4342     color = getPixelColor(device, 66, 430);
4343     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4344
4345     color = getPixelColor(device, 578, 430);
4346     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4347     color = getPixelColor(device, 578, 433);
4348     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4349     color = getPixelColor(device, 575, 433);
4350     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4351     color = getPixelColor(device, 575, 430);
4352     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4353
4354     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4355     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4356
4357     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4358     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4359     IDirect3DPixelShader9_Release(shader);
4360
4361     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4362     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4363     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4364     if(FAILED(hr)) {
4365         skip("Failed to create 2.0 test shader, most likely not supported\n");
4366         return;
4367     }
4368
4369     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4370     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4371     hr = IDirect3DDevice9_BeginScene(device);
4372     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4373     if(SUCCEEDED(hr))
4374     {
4375         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4376         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4377         hr = IDirect3DDevice9_EndScene(device);
4378         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4379     }
4380
4381     color = getPixelColor(device, 63, 46);
4382     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4383     color = getPixelColor(device, 66, 46);
4384     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4385     color = getPixelColor(device, 63, 49);
4386     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4387     color = getPixelColor(device, 66, 49);
4388     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4389
4390     color = getPixelColor(device, 578, 46);
4391     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4392     color = getPixelColor(device, 575, 46);
4393     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4394     color = getPixelColor(device, 578, 49);
4395     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4396     color = getPixelColor(device, 575, 49);
4397     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4398
4399     color = getPixelColor(device, 63, 430);
4400     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4401     color = getPixelColor(device, 63, 433);
4402     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4403     color = getPixelColor(device, 66, 433);
4404     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4405     color = getPixelColor(device, 66, 430);
4406     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4407
4408     color = getPixelColor(device, 578, 430);
4409     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4410     color = getPixelColor(device, 578, 433);
4411     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4412     color = getPixelColor(device, 575, 433);
4413     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4414     color = getPixelColor(device, 575, 430);
4415     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4416
4417     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4418     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4419
4420     /* Cleanup */
4421     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4422     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4423     IDirect3DPixelShader9_Release(shader);
4424 }
4425
4426 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4427 {
4428     IDirect3D9 *d3d9;
4429     HRESULT hr;
4430     IDirect3DTexture9 *texture;
4431     IDirect3DPixelShader9 *shader;
4432     IDirect3DPixelShader9 *shader2;
4433     D3DLOCKED_RECT lr;
4434     DWORD color;
4435     DWORD shader_code[] = {
4436         0xffff0101,                             /* ps_1_1       */
4437         0x00000042, 0xb00f0000,                 /* tex t0       */
4438         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4439         0x0000ffff                              /* end          */
4440     };
4441     DWORD shader_code2[] = {
4442         0xffff0101,                             /* ps_1_1       */
4443         0x00000042, 0xb00f0000,                 /* tex t0       */
4444         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4445         0x0000ffff                              /* end          */
4446     };
4447
4448     float quad[] = {
4449        -1.0,   -1.0,   0.1,     0.5,    0.5,
4450         1.0,   -1.0,   0.1,     0.5,    0.5,
4451        -1.0,    1.0,   0.1,     0.5,    0.5,
4452         1.0,    1.0,   0.1,     0.5,    0.5,
4453     };
4454
4455     memset(&lr, 0, sizeof(lr));
4456     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4457     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4458                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4459     IDirect3D9_Release(d3d9);
4460     if(FAILED(hr)) {
4461         skip("No D3DFMT_X8L8V8U8 support\n");
4462         return;
4463     };
4464
4465     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4466     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4467
4468     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4469     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4470     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4471     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4472     *((DWORD *) lr.pBits) = 0x11ca3141;
4473     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4474     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4475
4476     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4477     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4478     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4479     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4480
4481     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4482     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4483     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4484     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4485     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4486     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4487
4488     hr = IDirect3DDevice9_BeginScene(device);
4489     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4490     if(SUCCEEDED(hr))
4491     {
4492         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4493         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4494
4495         hr = IDirect3DDevice9_EndScene(device);
4496         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4497     }
4498     color = getPixelColor(device, 578, 430);
4499     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4500        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4501     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4502     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4503
4504     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4505     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4506     hr = IDirect3DDevice9_BeginScene(device);
4507     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4508     if(SUCCEEDED(hr))
4509     {
4510         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4511         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4512
4513         hr = IDirect3DDevice9_EndScene(device);
4514         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4515     }
4516     color = getPixelColor(device, 578, 430);
4517     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4518     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4519     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4520
4521     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4522     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4523     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4524     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4525     IDirect3DPixelShader9_Release(shader);
4526     IDirect3DPixelShader9_Release(shader2);
4527     IDirect3DTexture9_Release(texture);
4528 }
4529
4530 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4531 {
4532     HRESULT hr;
4533     IDirect3D9 *d3d;
4534     IDirect3DTexture9 *texture = NULL;
4535     IDirect3DSurface9 *surface;
4536     DWORD color;
4537     const RECT r1 = {256, 256, 512, 512};
4538     const RECT r2 = {512, 256, 768, 512};
4539     const RECT r3 = {256, 512, 512, 768};
4540     const RECT r4 = {512, 512, 768, 768};
4541     unsigned int x, y;
4542     D3DLOCKED_RECT lr;
4543     memset(&lr, 0, sizeof(lr));
4544
4545     IDirect3DDevice9_GetDirect3D(device, &d3d);
4546     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4547        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4548         skip("No autogenmipmap support\n");
4549         IDirect3D9_Release(d3d);
4550         return;
4551     }
4552     IDirect3D9_Release(d3d);
4553
4554     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4556
4557     /* Make the mipmap big, so that a smaller mipmap is used
4558      */
4559     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4560                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4561     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4562
4563     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4564     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4565     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4566     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4567     for(y = 0; y < 1024; y++) {
4568         for(x = 0; x < 1024; x++) {
4569             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4570             POINT pt;
4571
4572             pt.x = x;
4573             pt.y = y;
4574             if(PtInRect(&r1, pt)) {
4575                 *dst = 0xffff0000;
4576             } else if(PtInRect(&r2, pt)) {
4577                 *dst = 0xff00ff00;
4578             } else if(PtInRect(&r3, pt)) {
4579                 *dst = 0xff0000ff;
4580             } else if(PtInRect(&r4, pt)) {
4581                 *dst = 0xff000000;
4582             } else {
4583                 *dst = 0xffffffff;
4584             }
4585         }
4586     }
4587     hr = IDirect3DSurface9_UnlockRect(surface);
4588     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4589     IDirect3DSurface9_Release(surface);
4590
4591     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4592     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4593     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4594     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4595
4596     hr = IDirect3DDevice9_BeginScene(device);
4597     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4598     if(SUCCEEDED(hr)) {
4599         const float quad[] =  {
4600            -0.5,   -0.5,    0.1,    0.0,    0.0,
4601            -0.5,    0.5,    0.1,    0.0,    1.0,
4602             0.5,   -0.5,    0.1,    1.0,    0.0,
4603             0.5,    0.5,    0.1,    1.0,    1.0
4604         };
4605
4606         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4607         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4608         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4609         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4610         hr = IDirect3DDevice9_EndScene(device);
4611         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4612     }
4613     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4614     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4615     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4616     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4617     IDirect3DTexture9_Release(texture);
4618
4619     color = getPixelColor(device, 200, 200);
4620     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4621     color = getPixelColor(device, 280, 200);
4622     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4623     color = getPixelColor(device, 360, 200);
4624     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4625     color = getPixelColor(device, 440, 200);
4626     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4627     color = getPixelColor(device, 200, 270);
4628     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4629     color = getPixelColor(device, 280, 270);
4630     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4631     color = getPixelColor(device, 360, 270);
4632     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4633     color = getPixelColor(device, 440, 270);
4634     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4635     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4636     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4637 }
4638
4639 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4640 {
4641     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4642     IDirect3DVertexDeclaration9 *decl;
4643     HRESULT hr;
4644     DWORD color;
4645     DWORD shader_code_11[] =  {
4646         0xfffe0101,                                         /* vs_1_1           */
4647         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4648         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4649         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4650         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4651         0x0000ffff                                          /* end              */
4652     };
4653     DWORD shader_code_11_2[] =  {
4654         0xfffe0101,                                         /* vs_1_1           */
4655         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4656         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4657         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4658         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4659         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4660         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4661         0x0000ffff                                          /* end              */
4662     };
4663     DWORD shader_code_20[] =  {
4664         0xfffe0200,                                         /* vs_2_0           */
4665         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4666         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4667         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4668         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4669         0x0000ffff                                          /* end              */
4670     };
4671     DWORD shader_code_20_2[] =  {
4672         0xfffe0200,                                         /* vs_2_0           */
4673         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4674         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4675         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4676         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4677         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4678         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4679         0x0000ffff                                          /* end              */
4680     };
4681     static const D3DVERTEXELEMENT9 decl_elements[] = {
4682         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4683         D3DDECL_END()
4684     };
4685     float quad1[] = {
4686         -1.0,   -1.0,   0.1,
4687          0.0,   -1.0,   0.1,
4688         -1.0,    0.0,   0.1,
4689          0.0,    0.0,   0.1
4690     };
4691     float quad2[] = {
4692          0.0,   -1.0,   0.1,
4693          1.0,   -1.0,   0.1,
4694          0.0,    0.0,   0.1,
4695          1.0,    0.0,   0.1
4696     };
4697     float quad3[] = {
4698          0.0,    0.0,   0.1,
4699          1.0,    0.0,   0.1,
4700          0.0,    1.0,   0.1,
4701          1.0,    1.0,   0.1
4702     };
4703     float quad4[] = {
4704         -1.0,    0.0,   0.1,
4705          0.0,    0.0,   0.1,
4706         -1.0,    1.0,   0.1,
4707          0.0,    1.0,   0.1
4708     };
4709     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4710     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4711
4712     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4713     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4714
4715     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4716     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4717     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4718     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4719     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4720     if(FAILED(hr)) shader_20 = NULL;
4721     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4722     if(FAILED(hr)) shader_20_2 = NULL;
4723     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4724     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4725
4726     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4727     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4728     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4729     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4730     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4731     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4732
4733     hr = IDirect3DDevice9_BeginScene(device);
4734     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4735     if(SUCCEEDED(hr))
4736     {
4737         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4738         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4739         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4740         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4741
4742         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4743         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4744         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4745         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4746
4747         if(shader_20) {
4748             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4749             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4750             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4751             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4752         }
4753
4754         if(shader_20_2) {
4755             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4756             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4757             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4758             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4759         }
4760
4761         hr = IDirect3DDevice9_EndScene(device);
4762         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4763     }
4764
4765     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4767     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4768     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4769
4770     color = getPixelColor(device, 160, 360);
4771     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4772        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4773     color = getPixelColor(device, 480, 360);
4774     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4775        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4776     if(shader_20) {
4777         color = getPixelColor(device, 160, 120);
4778         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4779            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4780     }
4781     if(shader_20_2) {
4782         color = getPixelColor(device, 480, 120);
4783         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4784            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4785     }
4786     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4787     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4788
4789     IDirect3DVertexDeclaration9_Release(decl);
4790     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4791     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4792     IDirect3DVertexShader9_Release(shader_11_2);
4793     IDirect3DVertexShader9_Release(shader_11);
4794 }
4795
4796 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4797 {
4798     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4799     HRESULT hr;
4800     DWORD color;
4801     DWORD shader_code_11[] =  {
4802         0xffff0101,                                         /* ps_1_1           */
4803         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4804         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4805         0x0000ffff                                          /* end              */
4806     };
4807     DWORD shader_code_12[] =  {
4808         0xffff0102,                                         /* ps_1_2           */
4809         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4810         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4811         0x0000ffff                                          /* end              */
4812     };
4813     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4814      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4815      * During development of this test, 1.3 shaders were verified too
4816      */
4817     DWORD shader_code_14[] =  {
4818         0xffff0104,                                         /* ps_1_4           */
4819         /* Try to make one constant local. It gets clamped too, although the binary contains
4820          * the bigger numbers
4821          */
4822         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4823         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4824         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4825         0x0000ffff                                          /* end              */
4826     };
4827     DWORD shader_code_20[] =  {
4828         0xffff0200,                                         /* ps_2_0           */
4829         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4830         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4831         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4832         0x0000ffff                                          /* end              */
4833     };
4834     float quad1[] = {
4835         -1.0,   -1.0,   0.1,
4836          0.0,   -1.0,   0.1,
4837         -1.0,    0.0,   0.1,
4838          0.0,    0.0,   0.1
4839     };
4840     float quad2[] = {
4841          0.0,   -1.0,   0.1,
4842          1.0,   -1.0,   0.1,
4843          0.0,    0.0,   0.1,
4844          1.0,    0.0,   0.1
4845     };
4846     float quad3[] = {
4847          0.0,    0.0,   0.1,
4848          1.0,    0.0,   0.1,
4849          0.0,    1.0,   0.1,
4850          1.0,    1.0,   0.1
4851     };
4852     float quad4[] = {
4853         -1.0,    0.0,   0.1,
4854          0.0,    0.0,   0.1,
4855         -1.0,    1.0,   0.1,
4856          0.0,    1.0,   0.1
4857     };
4858     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4859     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4860
4861     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4862     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4863
4864     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4865     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4866     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4867     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4868     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4869     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4870     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4871     if(FAILED(hr)) shader_20 = NULL;
4872
4873     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4874     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4875     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4876     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4877     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4878     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4879
4880     hr = IDirect3DDevice9_BeginScene(device);
4881     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4882     if(SUCCEEDED(hr))
4883     {
4884         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4885         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4886         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4887         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4888
4889         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4890         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4891         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4892         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4893
4894         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4895         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4896         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4897         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4898
4899         if(shader_20) {
4900             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4901             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4902             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4903             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4904         }
4905
4906         hr = IDirect3DDevice9_EndScene(device);
4907         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4908     }
4909     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4910     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4911
4912     color = getPixelColor(device, 160, 360);
4913     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4914        "quad 1 has color %08x, expected 0x00808000\n", color);
4915     color = getPixelColor(device, 480, 360);
4916     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4917        "quad 2 has color %08x, expected 0x00808000\n", color);
4918     color = getPixelColor(device, 480, 120);
4919     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4920        "quad 3 has color %08x, expected 0x00808000\n", color);
4921     if(shader_20) {
4922         color = getPixelColor(device, 160, 120);
4923         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4924            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4925     }
4926     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4927     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4928
4929     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4930     IDirect3DPixelShader9_Release(shader_14);
4931     IDirect3DPixelShader9_Release(shader_12);
4932     IDirect3DPixelShader9_Release(shader_11);
4933 }
4934
4935 static void dp2add_ps_test(IDirect3DDevice9 *device)
4936 {
4937     IDirect3DPixelShader9 *shader_dp2add = NULL;
4938     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4939     HRESULT hr;
4940     DWORD color;
4941
4942     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4943      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4944      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4945      * r0 first.
4946      * The result here for the r,g,b components should be roughly 0.5:
4947      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4948     static const DWORD shader_code_dp2add[] =  {
4949         0xffff0200,                                                             /* ps_2_0                       */
4950         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4951
4952         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4953         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4954
4955         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4956         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4957         0x0000ffff                                                              /* end                          */
4958     };
4959
4960     /* Test the _sat modifier, too.  Result here should be:
4961      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4962      *      _SAT: ==> 1.0
4963      *   ADD: (1.0 + -0.5) = 0.5
4964      */
4965     static const DWORD shader_code_dp2add_sat[] =  {
4966         0xffff0200,                                                             /* ps_2_0                           */
4967         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4968
4969         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4970         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4971         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4972
4973         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4974         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4975         0x0000ffff                                                              /* end                              */
4976     };
4977
4978     const float quad[] = {
4979         -1.0,   -1.0,   0.1,
4980          1.0,   -1.0,   0.1,
4981         -1.0,    1.0,   0.1,
4982          1.0,    1.0,   0.1
4983     };
4984
4985
4986     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4987     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4988
4989     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4990     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4991
4992     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4993     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4994
4995     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4996     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4997
4998     if (shader_dp2add) {
4999
5000         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5001         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5002
5003         hr = IDirect3DDevice9_BeginScene(device);
5004         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5005         if(SUCCEEDED(hr))
5006         {
5007             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5008             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5009
5010             hr = IDirect3DDevice9_EndScene(device);
5011             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5012         }
5013
5014         color = getPixelColor(device, 360, 240);
5015         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5016                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5017
5018         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5019         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5020
5021         IDirect3DPixelShader9_Release(shader_dp2add);
5022     } else {
5023         skip("dp2add shader creation failed\n");
5024     }
5025
5026     if (shader_dp2add_sat) {
5027
5028         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5029         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5030
5031         hr = IDirect3DDevice9_BeginScene(device);
5032         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5033         if(SUCCEEDED(hr))
5034         {
5035             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5036             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5037
5038             hr = IDirect3DDevice9_EndScene(device);
5039             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5040         }
5041
5042         color = getPixelColor(device, 360, 240);
5043         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5044                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5045
5046         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5047         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5048
5049         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5050     } else {
5051         skip("dp2add shader creation failed\n");
5052     }
5053
5054     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5055     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5056 }
5057
5058 static void cnd_test(IDirect3DDevice9 *device)
5059 {
5060     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5061     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5062     HRESULT hr;
5063     DWORD color;
5064     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5065      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5066      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5067      */
5068     DWORD shader_code_11[] =  {
5069         0xffff0101,                                                                 /* ps_1_1               */
5070         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5071         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5072         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5073         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5074         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5075         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5076         0x0000ffff                                                                  /* end                  */
5077     };
5078     DWORD shader_code_12[] =  {
5079         0xffff0102,                                                                 /* ps_1_2               */
5080         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5081         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5082         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5083         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5084         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5085         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5086         0x0000ffff                                                                  /* end                  */
5087     };
5088     DWORD shader_code_13[] =  {
5089         0xffff0103,                                                                 /* ps_1_3               */
5090         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5091         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5092         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5093         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5094         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5095         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5096         0x0000ffff                                                                  /* end                  */
5097     };
5098     DWORD shader_code_14[] =  {
5099         0xffff0104,                                                                 /* ps_1_3               */
5100         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5101         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5102         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5103         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5104         0x0000ffff                                                                  /* end                  */
5105     };
5106
5107     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5108      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5109      * set by the compiler, it was added manually after compilation. It isn't always allowed,
5110      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
5111      * native CreatePixelShader returns an error.
5112      *
5113      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5114      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5115      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5116      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5117      */
5118     DWORD shader_code_11_coissue[] =  {
5119         0xffff0101,                                                             /* ps_1_1                   */
5120         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5121         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5122         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5123         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5124         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5125         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5126         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5127         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5128         /* 0x40000000 = D3DSI_COISSUE */
5129         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5130         0x0000ffff                                                              /* end                      */
5131     };
5132     DWORD shader_code_12_coissue[] =  {
5133         0xffff0102,                                                             /* ps_1_2                   */
5134         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5135         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5136         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5137         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5138         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5139         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5140         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5141         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5142         /* 0x40000000 = D3DSI_COISSUE */
5143         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5144         0x0000ffff                                                              /* end                      */
5145     };
5146     DWORD shader_code_13_coissue[] =  {
5147         0xffff0103,                                                             /* ps_1_3                   */
5148         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5149         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5150         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5151         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5152         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5153         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5154         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5155         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5156         /* 0x40000000 = D3DSI_COISSUE */
5157         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5158         0x0000ffff                                                              /* end                      */
5159     };
5160     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5161      * compare against 0.5
5162      */
5163     DWORD shader_code_14_coissue[] =  {
5164         0xffff0104,                                                             /* ps_1_4                   */
5165         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5166         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5167         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5168         /* 0x40000000 = D3DSI_COISSUE */
5169         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5170         0x0000ffff                                                              /* end                      */
5171     };
5172     float quad1[] = {
5173         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5174          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5175         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5176          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5177     };
5178     float quad2[] = {
5179          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5180          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5181          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5182          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5183     };
5184     float quad3[] = {
5185          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5186          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5187          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5188          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5189     };
5190     float quad4[] = {
5191         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5192          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5193         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5194          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5195     };
5196     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5197     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5198     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5199     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5200
5201     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5202     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5203
5204     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5205     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5206     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5207     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5208     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5209     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5210     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5211     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5212     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5213     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5214     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5215     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5216     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5217     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5218     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5219     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5220
5221     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5222     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5223     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5224     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5225     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5226     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5227
5228     hr = IDirect3DDevice9_BeginScene(device);
5229     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5230     if(SUCCEEDED(hr))
5231     {
5232         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5233         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5235         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5236
5237         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5238         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5239         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5240         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5241
5242         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5243         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5244         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5245         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5246
5247         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5248         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5249         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5250         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5251
5252         hr = IDirect3DDevice9_EndScene(device);
5253         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5254     }
5255
5256     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5257     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5258
5259     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5260     color = getPixelColor(device, 158, 118);
5261     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5262     color = getPixelColor(device, 162, 118);
5263     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5264     color = getPixelColor(device, 158, 122);
5265     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5266     color = getPixelColor(device, 162, 122);
5267     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5268
5269     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5270     color = getPixelColor(device, 158, 358);
5271     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5272     color = getPixelColor(device, 162, 358);
5273     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5274         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5275     color = getPixelColor(device, 158, 362);
5276     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5277     color = getPixelColor(device, 162, 362);
5278     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5279         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5280
5281     /* 1.2 shader */
5282     color = getPixelColor(device, 478, 358);
5283     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5284     color = getPixelColor(device, 482, 358);
5285     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5286         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5287     color = getPixelColor(device, 478, 362);
5288     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5289     color = getPixelColor(device, 482, 362);
5290     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5291         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5292
5293     /* 1.3 shader */
5294     color = getPixelColor(device, 478, 118);
5295     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5296     color = getPixelColor(device, 482, 118);
5297     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5298         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5299     color = getPixelColor(device, 478, 122);
5300     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5301     color = getPixelColor(device, 482, 122);
5302     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5303         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5304
5305     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5306     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5307
5308     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5309     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5310     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5311     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5312     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5313     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5314
5315     hr = IDirect3DDevice9_BeginScene(device);
5316     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5317     if(SUCCEEDED(hr))
5318     {
5319         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5320         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5323
5324         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5325         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5327         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5328
5329         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5330         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5331         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5332         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5333
5334         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5335         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5336         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5337         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5338
5339         hr = IDirect3DDevice9_EndScene(device);
5340         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5341     }
5342
5343     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5344     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5345
5346     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5347      * that we swapped the values in c1 and c2 to make the other tests return some color
5348      */
5349     color = getPixelColor(device, 158, 118);
5350     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5351     color = getPixelColor(device, 162, 118);
5352     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5353     color = getPixelColor(device, 158, 122);
5354     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5355     color = getPixelColor(device, 162, 122);
5356     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5357
5358     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5359     color = getPixelColor(device, 158, 358);
5360     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5361         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5362     color = getPixelColor(device, 162, 358);
5363     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5364         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5365     color = getPixelColor(device, 158, 362);
5366     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5367         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5368     color = getPixelColor(device, 162, 362);
5369     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5370         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5371
5372     /* 1.2 shader */
5373     color = getPixelColor(device, 478, 358);
5374     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5375         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5376     color = getPixelColor(device, 482, 358);
5377     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5378         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5379     color = getPixelColor(device, 478, 362);
5380     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5381         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5382     color = getPixelColor(device, 482, 362);
5383     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5384         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5385
5386     /* 1.3 shader */
5387     color = getPixelColor(device, 478, 118);
5388     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5389         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5390     color = getPixelColor(device, 482, 118);
5391     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5392         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5393     color = getPixelColor(device, 478, 122);
5394     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5395         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5396     color = getPixelColor(device, 482, 122);
5397     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5398         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5399
5400     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5401     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5402
5403     IDirect3DPixelShader9_Release(shader_14_coissue);
5404     IDirect3DPixelShader9_Release(shader_13_coissue);
5405     IDirect3DPixelShader9_Release(shader_12_coissue);
5406     IDirect3DPixelShader9_Release(shader_11_coissue);
5407     IDirect3DPixelShader9_Release(shader_14);
5408     IDirect3DPixelShader9_Release(shader_13);
5409     IDirect3DPixelShader9_Release(shader_12);
5410     IDirect3DPixelShader9_Release(shader_11);
5411 }
5412
5413 static void nested_loop_test(IDirect3DDevice9 *device) {
5414     const DWORD shader_code[] = {
5415         0xffff0300,                                                             /* ps_3_0               */
5416         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5417         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5418         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5419         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5420         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5421         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5422         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5423         0x0000001d,                                                             /* endloop              */
5424         0x0000001d,                                                             /* endloop              */
5425         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5426         0x0000ffff                                                              /* end                  */
5427     };
5428     IDirect3DPixelShader9 *shader;
5429     HRESULT hr;
5430     DWORD color;
5431     const float quad[] = {
5432         -1.0,   -1.0,   0.1,
5433          1.0,   -1.0,   0.1,
5434         -1.0,    1.0,   0.1,
5435          1.0,    1.0,   0.1
5436     };
5437
5438     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5439     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5440     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5441     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5442     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5443     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5444     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5445     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5446
5447     hr = IDirect3DDevice9_BeginScene(device);
5448     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5449     if(SUCCEEDED(hr))
5450     {
5451         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5452         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5453         hr = IDirect3DDevice9_EndScene(device);
5454         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5455     }
5456
5457     color = getPixelColor(device, 360, 240);
5458     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5459        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5460
5461     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5462     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5463
5464     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5465     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5466     IDirect3DPixelShader9_Release(shader);
5467 }
5468
5469 struct varying_test_struct
5470 {
5471     const DWORD             *shader_code;
5472     IDirect3DPixelShader9   *shader;
5473     DWORD                   color, color_rhw;
5474     const char              *name;
5475     BOOL                    todo, todo_rhw;
5476 };
5477
5478 struct hugeVertex
5479 {
5480     float pos_x,        pos_y,      pos_z,      rhw;
5481     float weight_1,     weight_2,   weight_3,   weight_4;
5482     float index_1,      index_2,    index_3,    index_4;
5483     float normal_1,     normal_2,   normal_3,   normal_4;
5484     float fog_1,        fog_2,      fog_3,      fog_4;
5485     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5486     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5487     float binormal_1,   binormal_2, binormal_3, binormal_4;
5488     float depth_1,      depth_2,    depth_3,    depth_4;
5489     DWORD diffuse, specular;
5490 };
5491
5492 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5493     /* dcl_position: fails to compile */
5494     const DWORD blendweight_code[] = {
5495         0xffff0300,                             /* ps_3_0                   */
5496         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5497         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5498         0x0000ffff                              /* end                      */
5499     };
5500     const DWORD blendindices_code[] = {
5501         0xffff0300,                             /* ps_3_0                   */
5502         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5503         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5504         0x0000ffff                              /* end                      */
5505     };
5506     const DWORD normal_code[] = {
5507         0xffff0300,                             /* ps_3_0                   */
5508         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5509         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5510         0x0000ffff                              /* end                      */
5511     };
5512     /* psize: fails? */
5513     const DWORD texcoord0_code[] = {
5514         0xffff0300,                             /* ps_3_0                   */
5515         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5516         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5517         0x0000ffff                              /* end                      */
5518     };
5519     const DWORD tangent_code[] = {
5520         0xffff0300,                             /* ps_3_0                   */
5521         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5522         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5523         0x0000ffff                              /* end                      */
5524     };
5525     const DWORD binormal_code[] = {
5526         0xffff0300,                             /* ps_3_0                   */
5527         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5528         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5529         0x0000ffff                              /* end                      */
5530     };
5531     /* tessfactor: fails */
5532     /* positiont: fails */
5533     const DWORD color_code[] = {
5534         0xffff0300,                             /* ps_3_0                   */
5535         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5536         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5537         0x0000ffff                              /* end                      */
5538     };
5539     const DWORD fog_code[] = {
5540         0xffff0300,                             /* ps_3_0                   */
5541         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5542         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5543         0x0000ffff                              /* end                      */
5544     };
5545     const DWORD depth_code[] = {
5546         0xffff0300,                             /* ps_3_0                   */
5547         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5548         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5549         0x0000ffff                              /* end                      */
5550     };
5551     const DWORD specular_code[] = {
5552         0xffff0300,                             /* ps_3_0                   */
5553         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5554         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5555         0x0000ffff                              /* end                      */
5556     };
5557     /* sample: fails */
5558
5559     struct varying_test_struct tests[] = {
5560        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5561        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5562        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5563        /* Why does dx not forward the texcoord? */
5564        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5565        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5566        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5567        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5568        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5569        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5570        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5571     };
5572     /* Declare a monster vertex type :-) */
5573     static const D3DVERTEXELEMENT9 decl_elements[] = {
5574         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5575         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5576         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5577         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5578         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5579         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5580         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5581         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5582         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5583         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5584         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5585         D3DDECL_END()
5586     };
5587     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5588         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5589         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5590         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5591         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5592         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5593         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5594         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5595         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5596         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5597         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5598         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5599         D3DDECL_END()
5600     };
5601     struct hugeVertex data[4] = {
5602         {
5603             -1.0,   -1.0,   0.1,    1.0,
5604              0.1,    0.1,   0.1,    0.1,
5605              0.2,    0.2,   0.2,    0.2,
5606              0.3,    0.3,   0.3,    0.3,
5607              0.4,    0.4,   0.4,    0.4,
5608              0.50,   0.55,  0.55,   0.55,
5609              0.6,    0.6,   0.6,    0.7,
5610              0.7,    0.7,   0.7,    0.6,
5611              0.8,    0.8,   0.8,    0.8,
5612              0xe6e6e6e6, /* 0.9 * 256 */
5613              0x224488ff  /* Nothing special */
5614         },
5615         {
5616              1.0,   -1.0,   0.1,    1.0,
5617              0.1,    0.1,   0.1,    0.1,
5618              0.2,    0.2,   0.2,    0.2,
5619              0.3,    0.3,   0.3,    0.3,
5620              0.4,    0.4,   0.4,    0.4,
5621              0.50,   0.55,  0.55,   0.55,
5622              0.6,    0.6,   0.6,    0.7,
5623              0.7,    0.7,   0.7,    0.6,
5624              0.8,    0.8,   0.8,    0.8,
5625              0xe6e6e6e6, /* 0.9 * 256 */
5626              0x224488ff /* Nothing special */
5627         },
5628         {
5629             -1.0,    1.0,   0.1,    1.0,
5630              0.1,    0.1,   0.1,    0.1,
5631              0.2,    0.2,   0.2,    0.2,
5632              0.3,    0.3,   0.3,    0.3,
5633              0.4,    0.4,   0.4,    0.4,
5634              0.50,   0.55,  0.55,   0.55,
5635              0.6,    0.6,   0.6,    0.7,
5636              0.7,    0.7,   0.7,    0.6,
5637              0.8,    0.8,   0.8,    0.8,
5638              0xe6e6e6e6, /* 0.9 * 256 */
5639              0x224488ff /* Nothing special */
5640         },
5641         {
5642              1.0,    1.0,   0.1,    1.0,
5643              0.1,    0.1,   0.1,    0.1,
5644              0.2,    0.2,   0.2,    0.2,
5645              0.3,    0.3,   0.3,    0.3,
5646              0.4,    0.4,   0.4,    0.4,
5647              0.50,   0.55,  0.55,   0.55,
5648              0.6,    0.6,   0.6,    0.7,
5649              0.7,    0.7,   0.7,    0.6,
5650              0.8,    0.8,   0.8,    0.8,
5651              0xe6e6e6e6, /* 0.9 * 256 */
5652              0x224488ff /* Nothing special */
5653         },
5654     };
5655     struct hugeVertex data2[4];
5656     IDirect3DVertexDeclaration9 *decl;
5657     IDirect3DVertexDeclaration9 *decl2;
5658     HRESULT hr;
5659     unsigned int i;
5660     DWORD color, r, g, b, r_e, g_e, b_e;
5661     BOOL drawok;
5662
5663     memcpy(data2, data, sizeof(data2));
5664     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5665     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5666     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5667     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5668
5669     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5670     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5671     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5672     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5673     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5674     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5675
5676     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5677     {
5678         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5679         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5680            tests[i].name, hr);
5681     }
5682
5683     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5684     {
5685         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5686         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5687
5688         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5689         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5690
5691         hr = IDirect3DDevice9_BeginScene(device);
5692         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5693         drawok = FALSE;
5694         if(SUCCEEDED(hr))
5695         {
5696             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5697             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5698             drawok = SUCCEEDED(hr);
5699             hr = IDirect3DDevice9_EndScene(device);
5700             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5701         }
5702
5703         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5704          * the failure and do not check the color if it failed
5705          */
5706         if(!drawok) {
5707             continue;
5708         }
5709
5710         color = getPixelColor(device, 360, 240);
5711         r = color & 0x00ff0000 >> 16;
5712         g = color & 0x0000ff00 >>  8;
5713         b = color & 0x000000ff;
5714         r_e = tests[i].color & 0x00ff0000 >> 16;
5715         g_e = tests[i].color & 0x0000ff00 >>  8;
5716         b_e = tests[i].color & 0x000000ff;
5717
5718         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5719         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5720
5721         if(tests[i].todo) {
5722             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5723                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5724                          tests[i].name, color, tests[i].color);
5725         } else {
5726             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5727                "Test %s returned color 0x%08x, expected 0x%08x\n",
5728                tests[i].name, color, tests[i].color);
5729         }
5730     }
5731
5732     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5733     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5734     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5735     {
5736         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5737         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5738
5739         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5740         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5741
5742         hr = IDirect3DDevice9_BeginScene(device);
5743         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5744         if(SUCCEEDED(hr))
5745         {
5746             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5747             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5748             hr = IDirect3DDevice9_EndScene(device);
5749             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5750         }
5751
5752         color = getPixelColor(device, 360, 240);
5753         r = color & 0x00ff0000 >> 16;
5754         g = color & 0x0000ff00 >>  8;
5755         b = color & 0x000000ff;
5756         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5757         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5758         b_e = tests[i].color_rhw & 0x000000ff;
5759
5760         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5761         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5762
5763         if(tests[i].todo_rhw) {
5764             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5765              * pipeline
5766              */
5767             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5768                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5769                          tests[i].name, color, tests[i].color_rhw);
5770         } else {
5771             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5772                "Test %s returned color 0x%08x, expected 0x%08x\n",
5773                tests[i].name, color, tests[i].color_rhw);
5774         }
5775     }
5776
5777     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5778     {
5779         IDirect3DPixelShader9_Release(tests[i].shader);
5780     }
5781
5782     IDirect3DVertexDeclaration9_Release(decl2);
5783     IDirect3DVertexDeclaration9_Release(decl);
5784 }
5785
5786 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5787     static const DWORD ps_code[] = {
5788     0xffff0300,                                                             /* ps_3_0                       */
5789     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5790     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5791     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5792     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5793     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5794     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5795     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5796     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5797     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5798
5799     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5800     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5801     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5802     0x0000001d,                                                             /* endloop                      */
5803     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5804     0x0000ffff                                                              /* end                          */
5805     };
5806     static const DWORD vs_1_code[] = {
5807     0xfffe0101,                                                             /* vs_1_1                       */
5808     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5809     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5810     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5811     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5812     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5813     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5814     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5815     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5816     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5817     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5818     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5819     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5820     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5821     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5822     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5823     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5824     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5825     0x0000ffff
5826     };
5827     DWORD vs_2_code[] = {
5828     0xfffe0200,                                                             /* vs_2_0                       */
5829     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5830     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5831     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5832     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5833     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5834     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5835     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5836     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5837     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5838     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5839     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5840     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5841     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5842     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5843     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5844     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5845     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5846     0x0000ffff                                                              /* end                          */
5847     };
5848     /* TODO: Define normal, tangent, blendweight and depth here */
5849     static const DWORD vs_3_code[] = {
5850     0xfffe0300,                                                             /* vs_3_0                       */
5851     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5852     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5853     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5854     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5855     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5856     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5857     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5858     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5859     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5860     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5861     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5862     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5863     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5864     0x0000ffff                                                              /* end                          */
5865     };
5866     float quad1[] =  {
5867         -1.0,   -1.0,   0.1,
5868          0.0,   -1.0,   0.1,
5869         -1.0,    0.0,   0.1,
5870          0.0,    0.0,   0.1
5871     };
5872     float quad2[] =  {
5873          0.0,   -1.0,   0.1,
5874          1.0,   -1.0,   0.1,
5875          0.0,    0.0,   0.1,
5876          1.0,    0.0,   0.1
5877     };
5878     float quad3[] =  {
5879         -1.0,    0.0,   0.1,
5880          0.0,    0.0,   0.1,
5881         -1.0,    1.0,   0.1,
5882          0.0,    1.0,   0.1
5883     };
5884
5885     HRESULT hr;
5886     DWORD color;
5887     IDirect3DPixelShader9 *pixelshader = NULL;
5888     IDirect3DVertexShader9 *vs_1_shader = NULL;
5889     IDirect3DVertexShader9 *vs_2_shader = NULL;
5890     IDirect3DVertexShader9 *vs_3_shader = NULL;
5891
5892     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5893     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5894
5895     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5896     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5897     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5898     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5899     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5900     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5901     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5903     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5904     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5905     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5906
5907     hr = IDirect3DDevice9_BeginScene(device);
5908     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5909     if(SUCCEEDED(hr))
5910     {
5911         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5912         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5913         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5914         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5915
5916         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5919         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5920
5921         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5922         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5924         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5925
5926         hr = IDirect3DDevice9_EndScene(device);
5927         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5928     }
5929
5930     color = getPixelColor(device, 160, 120);
5931     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5932        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5933     /* Accept two ways of oFog handling:
5934      *
5935      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5936      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5937      *
5938      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5939      *    This happens with software vertex processing and on Intel cards
5940      *
5941      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5942      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5943      */
5944     color = getPixelColor(device, 160, 360);
5945     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5946        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5947        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5948     color = getPixelColor(device, 480, 360);
5949     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5950        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5951        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5952
5953     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5955
5956     /* cleanup */
5957     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5958     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5959     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5960     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5961     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5962     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5963     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5964     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5965 }
5966
5967 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5968     static const DWORD vs_code[] = {
5969     0xfffe0300,                                                             /* vs_3_0                       */
5970     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5971     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5972     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5973     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5974     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5975     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5976     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5977     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5978     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5979     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5980     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5981     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5982     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5983
5984     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5985     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5986     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5987     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5988     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5989     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5990     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5991     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5992     0x0000ffff                                                              /* end                          */
5993     };
5994     static const DWORD ps_1_code[] = {
5995     0xffff0104,                                                             /* ps_1_4                       */
5996     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5997     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5998     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5999     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
6000     0x0000ffff                                                              /* end                          */
6001     };
6002     static const DWORD ps_2_code[] = {
6003     0xffff0200,                                                             /* ps_2_0                       */
6004     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
6005     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
6006     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
6007
6008     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6009     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
6010     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6011     0x0000ffff                                                              /* end                          */
6012     };
6013     static const DWORD ps_3_code[] = {
6014     0xffff0300,                                                             /* ps_3_0                       */
6015     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
6016     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
6017     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
6018
6019     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6020     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
6021     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
6022     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6023     0x0000ffff                                                              /* end                          */
6024     };
6025
6026     float quad1[] =  {
6027         -1.0,   -1.0,   0.1,
6028          0.0,   -1.0,   0.1,
6029         -1.0,    0.0,   0.1,
6030          0.0,    0.0,   0.1
6031     };
6032     float quad2[] =  {
6033          0.0,   -1.0,   0.1,
6034          1.0,   -1.0,   0.1,
6035          0.0,    0.0,   0.1,
6036          1.0,    0.0,   0.1
6037     };
6038     float quad3[] =  {
6039         -1.0,    0.0,   0.1,
6040          0.0,    0.0,   0.1,
6041         -1.0,    1.0,   0.1,
6042          0.0,    1.0,   0.1
6043     };
6044     float quad4[] =  {
6045          0.0,    0.0,   0.1,
6046          1.0,    0.0,   0.1,
6047          0.0,    1.0,   0.1,
6048          1.0,    1.0,   0.1
6049     };
6050
6051     HRESULT hr;
6052     DWORD color;
6053     IDirect3DVertexShader9 *vertexshader = NULL;
6054     IDirect3DPixelShader9 *ps_1_shader = NULL;
6055     IDirect3DPixelShader9 *ps_2_shader = NULL;
6056     IDirect3DPixelShader9 *ps_3_shader = NULL;
6057     IDirect3DTexture9 *texture = NULL;
6058     D3DLOCKED_RECT lr;
6059     unsigned int x, y;
6060
6061     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6062     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6063
6064     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6065     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6066     if(FAILED(hr)) {
6067         skip("D3DFMT_A16B16G16R16 textures not supported\n");
6068         return;
6069     }
6070     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6071     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6072     for(y = 0; y < 512; y++) {
6073         for(x = 0; x < 512; x++) {
6074             double r_f = (double) x / (double) 512;
6075             double g_f = (double) y / (double) 512;
6076             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6077             unsigned short r = (unsigned short) (r_f * 65535.0);
6078             unsigned short g = (unsigned short) (g_f * 65535.0);
6079             dst[0] = r;
6080             dst[1] = g;
6081             dst[2] = 0;
6082             dst[3] = 65535;
6083         }
6084     }
6085     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6086     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6087
6088     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6089     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6090     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6091     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6092     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6093     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6094     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6095     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6096     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6097     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6098     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6099
6100     hr = IDirect3DDevice9_BeginScene(device);
6101     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6102     if(SUCCEEDED(hr))
6103     {
6104         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6105         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6107         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6108
6109         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6110         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6111         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6112         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6113
6114         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6115         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6116         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6117         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6118
6119         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6120         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6121         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6122         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6123         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6124         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6125         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6126         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6127         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6128         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6129         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6130         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6131         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6132         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6133
6134         hr = IDirect3DDevice9_EndScene(device);
6135         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6136     }
6137
6138     color = getPixelColor(device, 160, 120);
6139     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6140        (color & 0x0000ff00) == 0x0000ff00 &&
6141        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6142        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6143     color = getPixelColor(device, 160, 360);
6144     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6145        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6146        (color & 0x000000ff) == 0x00000000,
6147        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6148     color = getPixelColor(device, 480, 360);
6149     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6150        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6151        (color & 0x000000ff) == 0x00000000,
6152        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6153     color = getPixelColor(device, 480, 160);
6154     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6155        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6156        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6157        (color & 0x000000ff) == 0x00000000),
6158        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6159
6160     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6161     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6162
6163     /* cleanup */
6164     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6165     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6166     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6167     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6168     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6169     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6170     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6171     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6172     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6173     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6174     if(texture) IDirect3DTexture9_Release(texture);
6175 }
6176
6177 static void test_compare_instructions(IDirect3DDevice9 *device)
6178 {
6179     DWORD shader_sge_vec_code[] = {
6180         0xfffe0101,                                         /* vs_1_1                   */
6181         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6182         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6183         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6184         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6185         0x0000ffff                                          /* end                      */
6186     };
6187     DWORD shader_slt_vec_code[] = {
6188         0xfffe0101,                                         /* vs_1_1                   */
6189         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6190         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6191         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6192         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6193         0x0000ffff                                          /* end                      */
6194     };
6195     DWORD shader_sge_scalar_code[] = {
6196         0xfffe0101,                                         /* vs_1_1                   */
6197         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6198         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6199         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6200         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6201         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6202         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6203         0x0000ffff                                          /* end                      */
6204     };
6205     DWORD shader_slt_scalar_code[] = {
6206         0xfffe0101,                                         /* vs_1_1                   */
6207         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6208         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6209         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6210         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6211         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6212         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6213         0x0000ffff                                          /* end                      */
6214     };
6215     IDirect3DVertexShader9 *shader_sge_vec;
6216     IDirect3DVertexShader9 *shader_slt_vec;
6217     IDirect3DVertexShader9 *shader_sge_scalar;
6218     IDirect3DVertexShader9 *shader_slt_scalar;
6219     HRESULT hr, color;
6220     float quad1[] =  {
6221         -1.0,   -1.0,   0.1,
6222          0.0,   -1.0,   0.1,
6223         -1.0,    0.0,   0.1,
6224          0.0,    0.0,   0.1
6225     };
6226     float quad2[] =  {
6227          0.0,   -1.0,   0.1,
6228          1.0,   -1.0,   0.1,
6229          0.0,    0.0,   0.1,
6230          1.0,    0.0,   0.1
6231     };
6232     float quad3[] =  {
6233         -1.0,    0.0,   0.1,
6234          0.0,    0.0,   0.1,
6235         -1.0,    1.0,   0.1,
6236          0.0,    1.0,   0.1
6237     };
6238     float quad4[] =  {
6239          0.0,    0.0,   0.1,
6240          1.0,    0.0,   0.1,
6241          0.0,    1.0,   0.1,
6242          1.0,    1.0,   0.1
6243     };
6244     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6245     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6246
6247     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6248     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6249
6250     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6251     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6252     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6253     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6254     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6255     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6256     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6257     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6258     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6259     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6260     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6261     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6262     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6263     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6264
6265     hr = IDirect3DDevice9_BeginScene(device);
6266     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6267     if(SUCCEEDED(hr))
6268     {
6269         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6270         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6272         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6273
6274         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6275         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6277         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6278
6279         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6280         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6281         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6282         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6283
6284         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6285         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6286
6287         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6288         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6289         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6290         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6291
6292         hr = IDirect3DDevice9_EndScene(device);
6293         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6294     }
6295
6296     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6297     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6298
6299     color = getPixelColor(device, 160, 360);
6300     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6301     color = getPixelColor(device, 480, 360);
6302     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6303     color = getPixelColor(device, 160, 120);
6304     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6305     color = getPixelColor(device, 480, 160);
6306     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6307
6308     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6309     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6310
6311     IDirect3DVertexShader9_Release(shader_sge_vec);
6312     IDirect3DVertexShader9_Release(shader_slt_vec);
6313     IDirect3DVertexShader9_Release(shader_sge_scalar);
6314     IDirect3DVertexShader9_Release(shader_slt_scalar);
6315 }
6316
6317 static void test_vshader_input(IDirect3DDevice9 *device)
6318 {
6319     DWORD swapped_shader_code_3[] = {
6320         0xfffe0300,                                         /* vs_3_0               */
6321         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6322         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6323         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6324         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6325         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6326         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6327         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6328         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6329         0x0000ffff                                          /* end                  */
6330     };
6331     DWORD swapped_shader_code_1[] = {
6332         0xfffe0101,                                         /* vs_1_1               */
6333         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6334         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6335         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6336         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6337         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6338         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6339         0x0000ffff                                          /* end                  */
6340     };
6341     DWORD swapped_shader_code_2[] = {
6342         0xfffe0200,                                         /* vs_2_0               */
6343         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6344         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6345         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6346         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6347         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6348         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6349         0x0000ffff                                          /* end                  */
6350     };
6351     DWORD texcoord_color_shader_code_3[] = {
6352         0xfffe0300,                                         /* vs_3_0               */
6353         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6354         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6355         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6356         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6357         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6358         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6359         0x0000ffff                                          /* end                  */
6360     };
6361     DWORD texcoord_color_shader_code_2[] = {
6362         0xfffe0200,                                         /* vs_2_0               */
6363         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6364         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6365         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6366         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6367         0x0000ffff                                          /* end                  */
6368     };
6369     DWORD texcoord_color_shader_code_1[] = {
6370         0xfffe0101,                                         /* vs_1_1               */
6371         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6372         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6373         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6374         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6375         0x0000ffff                                          /* end                  */
6376     };
6377     DWORD color_color_shader_code_3[] = {
6378         0xfffe0300,                                         /* vs_3_0               */
6379         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6380         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6381         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6382         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6383         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6384         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6385         0x0000ffff                                          /* end                  */
6386     };
6387     DWORD color_color_shader_code_2[] = {
6388         0xfffe0200,                                         /* vs_2_0               */
6389         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6390         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6391         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6392         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6393         0x0000ffff                                          /* end                  */
6394     };
6395     DWORD color_color_shader_code_1[] = {
6396         0xfffe0101,                                         /* vs_1_1               */
6397         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6398         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6399         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6400         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6401         0x0000ffff                                          /* end                  */
6402     };
6403     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6404     HRESULT hr;
6405     DWORD color;
6406     float quad1[] =  {
6407         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6408          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6409         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6410          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6411     };
6412     float quad2[] =  {
6413          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6414          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6415          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6416          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6417     };
6418     float quad3[] =  {
6419         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6420          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6421         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6422          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6423     };
6424     float quad4[] =  {
6425          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6426          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6427          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6428          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6429     };
6430     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6431         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6432         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6433         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6434         D3DDECL_END()
6435     };
6436     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6437         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6438         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6439         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6440         D3DDECL_END()
6441     };
6442     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6443         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6444         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6445         D3DDECL_END()
6446     };
6447     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6448         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6449         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6450         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6451         D3DDECL_END()
6452     };
6453     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6454         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6455         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6456         D3DDECL_END()
6457     };
6458     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6459         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6460         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6461         D3DDECL_END()
6462     };
6463     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6464         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6465         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6466         D3DDECL_END()
6467     };
6468     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6469         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6470         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6471         D3DDECL_END()
6472     };
6473     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6474     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6475     unsigned int i;
6476     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6477     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6478
6479     struct vertex quad1_color[] =  {
6480        {-1.0,   -1.0,   0.1,    0x00ff8040},
6481        { 0.0,   -1.0,   0.1,    0x00ff8040},
6482        {-1.0,    0.0,   0.1,    0x00ff8040},
6483        { 0.0,    0.0,   0.1,    0x00ff8040}
6484     };
6485     struct vertex quad2_color[] =  {
6486        { 0.0,   -1.0,   0.1,    0x00ff8040},
6487        { 1.0,   -1.0,   0.1,    0x00ff8040},
6488        { 0.0,    0.0,   0.1,    0x00ff8040},
6489        { 1.0,    0.0,   0.1,    0x00ff8040}
6490     };
6491     struct vertex quad3_color[] =  {
6492        {-1.0,    0.0,   0.1,    0x00ff8040},
6493        { 0.0,    0.0,   0.1,    0x00ff8040},
6494        {-1.0,    1.0,   0.1,    0x00ff8040},
6495        { 0.0,    1.0,   0.1,    0x00ff8040}
6496     };
6497     float quad4_color[] =  {
6498          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6499          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6500          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6501          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6502     };
6503
6504     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6506     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6507     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6508     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6510     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6511     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6512
6513     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6514     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6515     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6516     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6517     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6518     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6519     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6520     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6521
6522     for(i = 1; i <= 3; i++) {
6523         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6524         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6525         if(i == 3) {
6526             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6527             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6528         } else if(i == 2){
6529             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6530             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6531         } else if(i == 1) {
6532             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6533             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6534         }
6535
6536         hr = IDirect3DDevice9_BeginScene(device);
6537         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6538         if(SUCCEEDED(hr))
6539         {
6540             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6541             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6542
6543             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6544             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6545             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6546             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6547
6548             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6549             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6550             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6551             if(i == 3 || i == 2) {
6552                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6553             } else if(i == 1) {
6554                 /* Succeeds or fails, depending on SW or HW vertex processing */
6555                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6556             }
6557
6558             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6559             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6560             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6561             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6562
6563             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6564             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6565             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6566             if(i == 3 || i == 2) {
6567                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6568             } else if(i == 1) {
6569                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6570             }
6571
6572             hr = IDirect3DDevice9_EndScene(device);
6573             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6574         }
6575
6576         if(i == 3 || i == 2) {
6577             color = getPixelColor(device, 160, 360);
6578             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6579                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6580
6581             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6582             color = getPixelColor(device, 480, 360);
6583             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6584                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6585             color = getPixelColor(device, 160, 120);
6586             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6587             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6588                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6589
6590             color = getPixelColor(device, 480, 160);
6591             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6592         } else if(i == 1) {
6593             color = getPixelColor(device, 160, 360);
6594             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6595                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6596             color = getPixelColor(device, 480, 360);
6597             /* Accept the clear color as well in this case, since SW VP returns an error */
6598             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6599             color = getPixelColor(device, 160, 120);
6600             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6601                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6602             color = getPixelColor(device, 480, 160);
6603             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6604         }
6605
6606         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6607         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6608
6609         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6610         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6611
6612         /* Now find out if the whole streams are re-read, or just the last active value for the
6613          * vertices is used.
6614          */
6615         hr = IDirect3DDevice9_BeginScene(device);
6616         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6617         if(SUCCEEDED(hr))
6618         {
6619             float quad1_modified[] =  {
6620                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6621                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6622                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6623                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6624             };
6625             float quad2_modified[] =  {
6626                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6627                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6628                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6629                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6630             };
6631
6632             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6633             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6634
6635             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6636             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6637             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6638             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6639
6640             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6641             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6642             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6643             if(i == 3 || i == 2) {
6644                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6645             } else if(i == 1) {
6646                 /* Succeeds or fails, depending on SW or HW vertex processing */
6647                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6648             }
6649
6650             hr = IDirect3DDevice9_EndScene(device);
6651             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6652         }
6653
6654         color = getPixelColor(device, 480, 350);
6655         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6656          * as well.
6657          *
6658          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6659          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6660          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6661          * refrast's result.
6662          *
6663          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6664          */
6665         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6666            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6667
6668         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6669         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6670
6671         IDirect3DDevice9_SetVertexShader(device, NULL);
6672         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6673
6674         IDirect3DVertexShader9_Release(swapped_shader);
6675     }
6676
6677     for(i = 1; i <= 3; i++) {
6678         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6679         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6680         if(i == 3) {
6681             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6682             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6683             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6684             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6685         } else if(i == 2){
6686             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6687             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6688             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6689             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6690         } else if(i == 1) {
6691             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6692             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6693             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6694             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6695         }
6696
6697         hr = IDirect3DDevice9_BeginScene(device);
6698         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6699         if(SUCCEEDED(hr))
6700         {
6701             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6702             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6703             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6704             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6705             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6706             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6707
6708             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6709             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6710
6711             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6712             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6713             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6714             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6715             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6716             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6717
6718             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6719             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6720             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6721             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6722             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6723             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6724
6725             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6726             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6727             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6728             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6729
6730             hr = IDirect3DDevice9_EndScene(device);
6731             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6732         }
6733         IDirect3DDevice9_SetVertexShader(device, NULL);
6734         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6735
6736         color = getPixelColor(device, 160, 360);
6737         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6738            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6739         color = getPixelColor(device, 480, 360);
6740         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6741            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6742         color = getPixelColor(device, 160, 120);
6743         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6744            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6745         color = getPixelColor(device, 480, 160);
6746         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6747            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6748
6749         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6750         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6751
6752         IDirect3DVertexShader9_Release(texcoord_color_shader);
6753         IDirect3DVertexShader9_Release(color_color_shader);
6754     }
6755
6756     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6757     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6758     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6759     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6760
6761     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6762     IDirect3DVertexDeclaration9_Release(decl_color_color);
6763     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6764     IDirect3DVertexDeclaration9_Release(decl_color_float);
6765 }
6766
6767 static void srgbtexture_test(IDirect3DDevice9 *device)
6768 {
6769     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6770      * texture stage state to render a quad using that texture.  The resulting
6771      * color components should be 0x36 (~ 0.21), per this formula:
6772      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6773      * This is true where srgb_color > 0.04045.
6774      */
6775     IDirect3D9 *d3d = NULL;
6776     HRESULT hr;
6777     LPDIRECT3DTEXTURE9 texture = NULL;
6778     LPDIRECT3DSURFACE9 surface = NULL;
6779     D3DLOCKED_RECT lr;
6780     DWORD color;
6781     float quad[] = {
6782         -1.0,       1.0,       0.0,     0.0,    0.0,
6783          1.0,       1.0,       0.0,     1.0,    0.0,
6784         -1.0,      -1.0,       0.0,     0.0,    1.0,
6785          1.0,      -1.0,       0.0,     1.0,    1.0,
6786     };
6787
6788
6789     memset(&lr, 0, sizeof(lr));
6790     IDirect3DDevice9_GetDirect3D(device, &d3d);
6791     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6792                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6793                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6794         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6795         goto out;
6796     }
6797
6798     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6799                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6800                                         &texture, NULL);
6801     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6802     if(!texture) {
6803         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6804         goto out;
6805     }
6806     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6807     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6808
6809     fill_surface(surface, 0xff7f7f7f);
6810     IDirect3DSurface9_Release(surface);
6811
6812     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6813     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6814     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6815     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6816
6817     hr = IDirect3DDevice9_BeginScene(device);
6818     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6819     if(SUCCEEDED(hr))
6820     {
6821         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6822         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6823
6824         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6825         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6826
6827
6828         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6829         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6830
6831         hr = IDirect3DDevice9_EndScene(device);
6832         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6833     }
6834
6835     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6836     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6837     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6838     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6839
6840     color = getPixelColor(device, 320, 240);
6841     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6842
6843     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6844     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6845
6846 out:
6847     if(texture) IDirect3DTexture9_Release(texture);
6848     IDirect3D9_Release(d3d);
6849 }
6850
6851 static void shademode_test(IDirect3DDevice9 *device)
6852 {
6853     /* Render a quad and try all of the different fixed function shading models. */
6854     HRESULT hr;
6855     DWORD color0, color1;
6856     DWORD color0_gouraud = 0, color1_gouraud = 0;
6857     DWORD shademode = D3DSHADE_FLAT;
6858     DWORD primtype = D3DPT_TRIANGLESTRIP;
6859     LPVOID data = NULL;
6860     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6861     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6862     UINT i, j;
6863     struct vertex quad_strip[] =
6864     {
6865         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6866         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6867         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6868         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6869     };
6870     struct vertex quad_list[] =
6871     {
6872         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6873         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6874         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6875
6876         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6877         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6878         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6879     };
6880
6881     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6882                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6883     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6884     if (FAILED(hr)) goto bail;
6885
6886     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6887                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6888     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6889     if (FAILED(hr)) goto bail;
6890
6891     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6892     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6893
6894     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6895     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6896
6897     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6898     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6899     memcpy(data, quad_strip, sizeof(quad_strip));
6900     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6901     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6902
6903     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6904     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6905     memcpy(data, quad_list, sizeof(quad_list));
6906     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6907     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6908
6909     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6910      * the color fixups we have to do for FLAT shading will be dependent on that. */
6911     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6912     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6913
6914     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6915     for (j=0; j<2; j++) {
6916
6917         /* Inner loop just changes the D3DRS_SHADEMODE */
6918         for (i=0; i<3; i++) {
6919             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6920             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6921
6922             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6923             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6924
6925             hr = IDirect3DDevice9_BeginScene(device);
6926             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6927             if(SUCCEEDED(hr))
6928             {
6929                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6930                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6931
6932                 hr = IDirect3DDevice9_EndScene(device);
6933                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6934             }
6935
6936             /* Sample two spots from the output */
6937             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6938             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6939             switch(shademode) {
6940                 case D3DSHADE_FLAT:
6941                     /* Should take the color of the first vertex of each triangle */
6942                     if (0)
6943                     {
6944                         /* This test depends on EXT_provoking_vertex being
6945                          * available. This extension is currently (20090810)
6946                          * not common enough to let the test fail if it isn't
6947                          * present. */
6948                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6949                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6950                     }
6951                     shademode = D3DSHADE_GOURAUD;
6952                     break;
6953                 case D3DSHADE_GOURAUD:
6954                     /* Should be an interpolated blend */
6955
6956                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6957                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6958                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6959                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6960
6961                     color0_gouraud = color0;
6962                     color1_gouraud = color1;
6963
6964                     shademode = D3DSHADE_PHONG;
6965                     break;
6966                 case D3DSHADE_PHONG:
6967                     /* Should be the same as GOURAUD, since no hardware implements this */
6968                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6969                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6970                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6971                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6972
6973                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6974                             color0_gouraud, color0);
6975                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6976                             color1_gouraud, color1);
6977                     break;
6978             }
6979         }
6980
6981         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6982         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6983
6984         /* Now, do it all over again with a TRIANGLELIST */
6985         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6986         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6987         primtype = D3DPT_TRIANGLELIST;
6988         shademode = D3DSHADE_FLAT;
6989     }
6990
6991 bail:
6992     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6993     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6994     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6995     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6996
6997     if (vb_strip)
6998         IDirect3DVertexBuffer9_Release(vb_strip);
6999     if (vb_list)
7000         IDirect3DVertexBuffer9_Release(vb_list);
7001 }
7002
7003
7004 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
7005 {
7006     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
7007      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
7008      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
7009      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
7010      * 0.73
7011      *
7012      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
7013      * so use shaders for this task
7014      */
7015     IDirect3DPixelShader9 *pshader;
7016     IDirect3DVertexShader9 *vshader;
7017     IDirect3D9 *d3d;
7018     DWORD vshader_code[] = {
7019         0xfffe0101,                                                             /* vs_1_1                       */
7020         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
7021         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
7022         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
7023         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
7024         0x0000ffff                                                              /* end                          */
7025     };
7026     DWORD pshader_code[] = {
7027         0xffff0101,                                                             /* ps_1_1                       */
7028         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
7029         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
7030         0x0000ffff                                                              /* end                          */
7031     };
7032     const float quad[] = {
7033        -1.0,   -1.0,    0.1,
7034         1.0,   -1.0,    0.1,
7035        -1.0,    1.0,    0.1,
7036         1.0,    1.0,    0.1
7037     };
7038     HRESULT hr;
7039     D3DCOLOR color;
7040
7041     IDirect3DDevice9_GetDirect3D(device, &d3d);
7042     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
7043      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
7044      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
7045      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
7046      * works
7047      */
7048     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7049                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
7050                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
7051         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
7052         IDirect3D9_Release(d3d);
7053         return;
7054     }
7055     IDirect3D9_Release(d3d);
7056
7057     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
7058     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7059
7060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
7061     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
7063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
7065     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7066     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
7067     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7068     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
7069     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7070
7071     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7072     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7073     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
7074     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7075     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7076     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
7077     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7078     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7079     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
7080     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7081
7082     hr = IDirect3DDevice9_BeginScene(device);
7083     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7084     if(SUCCEEDED(hr)) {
7085         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
7086         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7087
7088         hr = IDirect3DDevice9_EndScene(device);
7089         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7090     }
7091
7092     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7093     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7094     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7095     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7096     IDirect3DPixelShader9_Release(pshader);
7097     IDirect3DVertexShader9_Release(vshader);
7098
7099     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
7100     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7101     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
7102     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7103
7104     color = getPixelColor(device, 160, 360);
7105     ok(color_match(color, 0x00808080, 1),
7106             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
7107     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7108     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7109 }
7110
7111 static void alpha_test(IDirect3DDevice9 *device)
7112 {
7113     HRESULT hr;
7114     IDirect3DTexture9 *offscreenTexture;
7115     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7116     DWORD color;
7117
7118     struct vertex quad1[] =
7119     {
7120         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7121         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7122         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7123         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7124     };
7125     struct vertex quad2[] =
7126     {
7127         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7128         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7129         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7130         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7131     };
7132     static const float composite_quad[][5] = {
7133         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7134         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7135         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7136         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7137     };
7138
7139     /* Clear the render target with alpha = 0.5 */
7140     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7141     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7142
7143     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7144     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7145
7146     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7147     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7148     if(!backbuffer) {
7149         goto out;
7150     }
7151
7152     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7153     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7154     if(!offscreen) {
7155         goto out;
7156     }
7157
7158     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7159     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7160
7161     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7162     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7163     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7164     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7165     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7166     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7167     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7168     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7169     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7170     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7171
7172     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7173     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7174     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7175
7176         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7177         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7178         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7179         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7180         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7181         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7182         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7183
7184         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7185         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7186         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7187         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7188         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7189         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7190
7191         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7192          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7193          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7194         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7195         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7196         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7197         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7198
7199         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7200         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7201         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7202         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7203         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7204         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7205
7206         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7207         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7208         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7209         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7210         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7211         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7212
7213         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7214         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7215
7216         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7217          * Disable alpha blending for the final composition
7218          */
7219         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7220         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7221         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7222         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7223
7224         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7225         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7226         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7227         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7228         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7229         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7230
7231         hr = IDirect3DDevice9_EndScene(device);
7232         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7233     }
7234
7235     color = getPixelColor(device, 160, 360);
7236     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7237        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7238
7239     color = getPixelColor(device, 160, 120);
7240     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7241        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7242
7243     color = getPixelColor(device, 480, 360);
7244     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7245        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7246
7247     color = getPixelColor(device, 480, 120);
7248     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7249        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7250
7251     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7252
7253     out:
7254     /* restore things */
7255     if(backbuffer) {
7256         IDirect3DSurface9_Release(backbuffer);
7257     }
7258     if(offscreenTexture) {
7259         IDirect3DTexture9_Release(offscreenTexture);
7260     }
7261     if(offscreen) {
7262         IDirect3DSurface9_Release(offscreen);
7263     }
7264 }
7265
7266 struct vertex_shortcolor {
7267     float x, y, z;
7268     unsigned short r, g, b, a;
7269 };
7270 struct vertex_floatcolor {
7271     float x, y, z;
7272     float r, g, b, a;
7273 };
7274
7275 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7276 {
7277     HRESULT hr;
7278     BOOL s_ok, ub_ok, f_ok;
7279     DWORD color, size, i;
7280     void *data;
7281     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7282         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7283         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7284         D3DDECL_END()
7285     };
7286     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7287         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7288         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7289         D3DDECL_END()
7290     };
7291     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7292         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7293         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7294         D3DDECL_END()
7295     };
7296     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7297         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7298         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7299         D3DDECL_END()
7300     };
7301     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7302         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7303         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7304         D3DDECL_END()
7305     };
7306     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7307         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7308         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7309         D3DDECL_END()
7310     };
7311     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7312         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7313         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7314         D3DDECL_END()
7315     };
7316     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7317     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7318     IDirect3DVertexBuffer9 *vb, *vb2;
7319     struct vertex quad1[] =                             /* D3DCOLOR */
7320     {
7321         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7322         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7323         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7324         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7325     };
7326     struct vertex quad2[] =                             /* UBYTE4N */
7327     {
7328         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7329         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7330         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7331         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7332     };
7333     struct vertex_shortcolor quad3[] =                  /* short */
7334     {
7335         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7336         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7337         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7338         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7339     };
7340     struct vertex_floatcolor quad4[] =
7341     {
7342         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7343         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7344         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7345         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7346     };
7347     DWORD colors[] = {
7348         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7349         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7350         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7351         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7352         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7353         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7354         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7355         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7356         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7357         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7358         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7359         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7360         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7361         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7362         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7363         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7364     };
7365     float quads[] = {
7366         -1.0,   -1.0,     0.1,
7367         -1.0,    0.0,     0.1,
7368          0.0,   -1.0,     0.1,
7369          0.0,    0.0,     0.1,
7370
7371          0.0,   -1.0,     0.1,
7372          0.0,    0.0,     0.1,
7373          1.0,   -1.0,     0.1,
7374          1.0,    0.0,     0.1,
7375
7376          0.0,    0.0,     0.1,
7377          0.0,    1.0,     0.1,
7378          1.0,    0.0,     0.1,
7379          1.0,    1.0,     0.1,
7380
7381         -1.0,    0.0,     0.1,
7382         -1.0,    1.0,     0.1,
7383          0.0,    0.0,     0.1,
7384          0.0,    1.0,     0.1
7385     };
7386     struct tvertex quad_transformed[] = {
7387        {  90,    110,     0.1,      2.0,        0x00ffff00},
7388        { 570,    110,     0.1,      2.0,        0x00ffff00},
7389        {  90,    300,     0.1,      2.0,        0x00ffff00},
7390        { 570,    300,     0.1,      2.0,        0x00ffff00}
7391     };
7392     D3DCAPS9 caps;
7393
7394     memset(&caps, 0, sizeof(caps));
7395     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7396     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7397
7398     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7399     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7400
7401     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7402     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7403     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7404     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7405     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7406     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7407     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7408         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7409         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7410         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7411         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7412     } else {
7413         trace("D3DDTCAPS_UBYTE4N not supported\n");
7414         dcl_ubyte_2 = NULL;
7415         dcl_ubyte = NULL;
7416     }
7417     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7418     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7419     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7420     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7421
7422     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7423     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7424                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7425     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7426
7427     hr = IDirect3DDevice9_BeginScene(device);
7428     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7429     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7430     if(SUCCEEDED(hr)) {
7431         if(dcl_color) {
7432             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7433             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7434             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7435             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7436         }
7437
7438         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7439          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7440          * using software vertex processing. Doh!
7441          */
7442         if(dcl_ubyte) {
7443             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7444             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7445             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7446             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7447             ub_ok = SUCCEEDED(hr);
7448         }
7449
7450         if(dcl_short) {
7451             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7452             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7453             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7454             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7455             s_ok = SUCCEEDED(hr);
7456         }
7457
7458         if(dcl_float) {
7459             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7460             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7461             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7462             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7463             f_ok = SUCCEEDED(hr);
7464         }
7465
7466         hr = IDirect3DDevice9_EndScene(device);
7467         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7468     }
7469
7470     if(dcl_short) {
7471         color = getPixelColor(device, 480, 360);
7472         ok(color == 0x000000ff || !s_ok,
7473            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7474     }
7475     if(dcl_ubyte) {
7476         color = getPixelColor(device, 160, 120);
7477         ok(color == 0x0000ffff || !ub_ok,
7478            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7479     }
7480     if(dcl_color) {
7481         color = getPixelColor(device, 160, 360);
7482         ok(color == 0x00ffff00,
7483            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7484     }
7485     if(dcl_float) {
7486         color = getPixelColor(device, 480, 120);
7487         ok(color == 0x00ff0000 || !f_ok,
7488            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7489     }
7490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7491
7492     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7493      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7494      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7495      * whether the immediate mode code works
7496      */
7497     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7498     hr = IDirect3DDevice9_BeginScene(device);
7499     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7500     if(SUCCEEDED(hr)) {
7501         if(dcl_color) {
7502             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7503             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7504             memcpy(data, quad1, sizeof(quad1));
7505             hr = IDirect3DVertexBuffer9_Unlock(vb);
7506             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7507             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7508             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7509             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7510             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7511             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7512             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7513         }
7514
7515         if(dcl_ubyte) {
7516             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7517             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7518             memcpy(data, quad2, sizeof(quad2));
7519             hr = IDirect3DVertexBuffer9_Unlock(vb);
7520             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7521             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7522             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7523             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7524             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7525             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7526             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7527                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7528             ub_ok = SUCCEEDED(hr);
7529         }
7530
7531         if(dcl_short) {
7532             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7533             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7534             memcpy(data, quad3, sizeof(quad3));
7535             hr = IDirect3DVertexBuffer9_Unlock(vb);
7536             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7537             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7538             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7539             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7540             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7541             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7542             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7543                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7544             s_ok = SUCCEEDED(hr);
7545         }
7546
7547         if(dcl_float) {
7548             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7549             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7550             memcpy(data, quad4, sizeof(quad4));
7551             hr = IDirect3DVertexBuffer9_Unlock(vb);
7552             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7553             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7554             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7555             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7556             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7557             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7558             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7559                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7560             f_ok = SUCCEEDED(hr);
7561         }
7562
7563         hr = IDirect3DDevice9_EndScene(device);
7564         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7565     }
7566
7567     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7568     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7569     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7570     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7571
7572     if(dcl_short) {
7573         color = getPixelColor(device, 480, 360);
7574         ok(color == 0x000000ff || !s_ok,
7575            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7576     }
7577     if(dcl_ubyte) {
7578         color = getPixelColor(device, 160, 120);
7579         ok(color == 0x0000ffff || !ub_ok,
7580            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7581     }
7582     if(dcl_color) {
7583         color = getPixelColor(device, 160, 360);
7584         ok(color == 0x00ffff00,
7585            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7586     }
7587     if(dcl_float) {
7588         color = getPixelColor(device, 480, 120);
7589         ok(color == 0x00ff0000 || !f_ok,
7590            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7591     }
7592     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7593
7594     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7595     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7596
7597     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7598     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7599     memcpy(data, quad_transformed, sizeof(quad_transformed));
7600     hr = IDirect3DVertexBuffer9_Unlock(vb);
7601     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7602
7603     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7604     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7605
7606     hr = IDirect3DDevice9_BeginScene(device);
7607     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7608     if(SUCCEEDED(hr)) {
7609         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7610         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7611         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7612         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7613
7614         hr = IDirect3DDevice9_EndScene(device);
7615         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7616     }
7617
7618     color = getPixelColor(device, 88, 108);
7619     ok(color == 0x000000ff,
7620        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7621     color = getPixelColor(device, 92, 108);
7622     ok(color == 0x000000ff,
7623        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7624     color = getPixelColor(device, 88, 112);
7625     ok(color == 0x000000ff,
7626        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7627     color = getPixelColor(device, 92, 112);
7628     ok(color == 0x00ffff00,
7629        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7630
7631     color = getPixelColor(device, 568, 108);
7632     ok(color == 0x000000ff,
7633        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7634     color = getPixelColor(device, 572, 108);
7635     ok(color == 0x000000ff,
7636        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7637     color = getPixelColor(device, 568, 112);
7638     ok(color == 0x00ffff00,
7639        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7640     color = getPixelColor(device, 572, 112);
7641     ok(color == 0x000000ff,
7642        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7643
7644     color = getPixelColor(device, 88, 298);
7645     ok(color == 0x000000ff,
7646        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7647     color = getPixelColor(device, 92, 298);
7648     ok(color == 0x00ffff00,
7649        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7650     color = getPixelColor(device, 88, 302);
7651     ok(color == 0x000000ff,
7652        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7653     color = getPixelColor(device, 92, 302);
7654     ok(color == 0x000000ff,
7655        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7656
7657     color = getPixelColor(device, 568, 298);
7658     ok(color == 0x00ffff00,
7659        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7660     color = getPixelColor(device, 572, 298);
7661     ok(color == 0x000000ff,
7662        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7663     color = getPixelColor(device, 568, 302);
7664     ok(color == 0x000000ff,
7665        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7666     color = getPixelColor(device, 572, 302);
7667     ok(color == 0x000000ff,
7668        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7669
7670     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7671
7672     /* This test is pointless without those two declarations: */
7673     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7674         skip("color-ubyte switching test declarations aren't supported\n");
7675         goto out;
7676     }
7677
7678     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7679     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7680     memcpy(data, quads, sizeof(quads));
7681     hr = IDirect3DVertexBuffer9_Unlock(vb);
7682     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7683     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7684                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7685     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7686     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7687     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7688     memcpy(data, colors, sizeof(colors));
7689     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7690     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7691
7692     for(i = 0; i < 2; i++) {
7693         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7694         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7695
7696         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7697         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7698         if(i == 0) {
7699             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7700         } else {
7701             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7702         }
7703         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7704
7705         hr = IDirect3DDevice9_BeginScene(device);
7706         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7707         ub_ok = FALSE;
7708         if(SUCCEEDED(hr)) {
7709             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7710             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7711             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7712             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7713                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7714             ub_ok = SUCCEEDED(hr);
7715
7716             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7717             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7718             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7719             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7720
7721             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7722             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7723             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7724             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7725                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7726             ub_ok = (SUCCEEDED(hr) && ub_ok);
7727
7728             hr = IDirect3DDevice9_EndScene(device);
7729             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7730         }
7731
7732         if(i == 0) {
7733             color = getPixelColor(device, 480, 360);
7734             ok(color == 0x00ff0000,
7735                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7736             color = getPixelColor(device, 160, 120);
7737             ok(color == 0x00ffffff,
7738                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7739             color = getPixelColor(device, 160, 360);
7740             ok(color == 0x000000ff || !ub_ok,
7741                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7742             color = getPixelColor(device, 480, 120);
7743             ok(color == 0x000000ff || !ub_ok,
7744                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7745         } else {
7746             color = getPixelColor(device, 480, 360);
7747             ok(color == 0x000000ff,
7748                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7749             color = getPixelColor(device, 160, 120);
7750             ok(color == 0x00ffffff,
7751                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7752             color = getPixelColor(device, 160, 360);
7753             ok(color == 0x00ff0000 || !ub_ok,
7754                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7755             color = getPixelColor(device, 480, 120);
7756             ok(color == 0x00ff0000 || !ub_ok,
7757                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7758         }
7759         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7760     }
7761
7762     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7763     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7764     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7765     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7766     IDirect3DVertexBuffer9_Release(vb2);
7767
7768     out:
7769     IDirect3DVertexBuffer9_Release(vb);
7770     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7771     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7772     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7773     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7774     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7775     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7776     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7777 }
7778
7779 struct vertex_float16color {
7780     float x, y, z;
7781     DWORD c1, c2;
7782 };
7783
7784 static void test_vshader_float16(IDirect3DDevice9 *device)
7785 {
7786     HRESULT hr;
7787     DWORD color;
7788     void *data;
7789     static const D3DVERTEXELEMENT9 decl_elements[] = {
7790         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7791         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7792         D3DDECL_END()
7793     };
7794     IDirect3DVertexDeclaration9 *vdecl = NULL;
7795     IDirect3DVertexBuffer9 *buffer = NULL;
7796     IDirect3DVertexShader9 *shader;
7797     DWORD shader_code[] = {
7798         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7799         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7800         0x90e40001, 0x0000ffff
7801     };
7802     struct vertex_float16color quad[] = {
7803         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7804         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7805         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7806         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7807
7808         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7809         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7810         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7811         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7812
7813         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7814         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7815         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7816         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7817
7818         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7819         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7820         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7821         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7822     };
7823
7824     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7825     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7826
7827     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7828     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7829     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7830     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7831     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7832     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7833
7834     hr = IDirect3DDevice9_BeginScene(device);
7835     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7836     if(SUCCEEDED(hr)) {
7837         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7838         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7839         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7840         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7841         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7842         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7843         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7844         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7845         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7846         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7847
7848         hr = IDirect3DDevice9_EndScene(device);
7849         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7850     }
7851     color = getPixelColor(device, 480, 360);
7852     ok(color == 0x00ff0000,
7853        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7854     color = getPixelColor(device, 160, 120);
7855     ok(color == 0x00000000,
7856        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7857     color = getPixelColor(device, 160, 360);
7858     ok(color == 0x0000ff00,
7859        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7860     color = getPixelColor(device, 480, 120);
7861     ok(color == 0x000000ff,
7862        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7863     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7864
7865     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7866     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7867
7868     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7869                                              D3DPOOL_MANAGED, &buffer, NULL);
7870     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7871     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7872     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7873     memcpy(data, quad, sizeof(quad));
7874     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7875     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7876     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7877     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7878
7879     hr = IDirect3DDevice9_BeginScene(device);
7880     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7881     if(SUCCEEDED(hr)) {
7882             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7883             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7884             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7885             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7886             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7887             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7888             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7889             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7890
7891             hr = IDirect3DDevice9_EndScene(device);
7892             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7893     }
7894
7895     color = getPixelColor(device, 480, 360);
7896     ok(color == 0x00ff0000,
7897        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7898     color = getPixelColor(device, 160, 120);
7899     ok(color == 0x00000000,
7900        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7901     color = getPixelColor(device, 160, 360);
7902     ok(color == 0x0000ff00,
7903        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7904     color = getPixelColor(device, 480, 120);
7905     ok(color == 0x000000ff,
7906        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7907     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7908
7909     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7910     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7911     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7912     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7913     IDirect3DDevice9_SetVertexShader(device, NULL);
7914     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7915
7916     IDirect3DVertexDeclaration9_Release(vdecl);
7917     IDirect3DVertexShader9_Release(shader);
7918     IDirect3DVertexBuffer9_Release(buffer);
7919 }
7920
7921 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7922 {
7923     D3DCAPS9 caps;
7924     IDirect3DTexture9 *texture;
7925     HRESULT hr;
7926     D3DLOCKED_RECT rect;
7927     unsigned int x, y;
7928     DWORD *dst, color;
7929     const float quad[] = {
7930         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7931          1.0,   -1.0,   0.1,    1.2,   -0.2,
7932         -1.0,    1.0,   0.1,   -0.2,    1.2,
7933          1.0,    1.0,   0.1,    1.2,    1.2
7934     };
7935     memset(&caps, 0, sizeof(caps));
7936
7937     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7938     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7939     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7940         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7941         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7942            "Card has conditional NP2 support without power of two restriction set\n");
7943         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7944         return;
7945     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7946         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7947         return;
7948     }
7949
7950     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7951     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7952
7953     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7954     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7955
7956     memset(&rect, 0, sizeof(rect));
7957     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7958     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7959     for(y = 0; y < 10; y++) {
7960         for(x = 0; x < 10; x++) {
7961             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7962             if(x == 0 || x == 9 || y == 0 || y == 9) {
7963                 *dst = 0x00ff0000;
7964             } else {
7965                 *dst = 0x000000ff;
7966             }
7967         }
7968     }
7969     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7970     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7971
7972     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7973     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7974     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7975     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7976     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7977     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7978     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7979     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7980
7981     hr = IDirect3DDevice9_BeginScene(device);
7982     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7983     if(SUCCEEDED(hr)) {
7984         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7985         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7986
7987         hr = IDirect3DDevice9_EndScene(device);
7988         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7989     }
7990
7991     color = getPixelColor(device,    1,  1);
7992     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7993     color = getPixelColor(device, 639, 479);
7994     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7995
7996     color = getPixelColor(device, 135, 101);
7997     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7998     color = getPixelColor(device, 140, 101);
7999     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8000     color = getPixelColor(device, 135, 105);
8001     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8002     color = getPixelColor(device, 140, 105);
8003     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8004
8005     color = getPixelColor(device, 135, 376);
8006     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8007     color = getPixelColor(device, 140, 376);
8008     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8009     color = getPixelColor(device, 135, 379);
8010     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8011     color = getPixelColor(device, 140, 379);
8012     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8013
8014     color = getPixelColor(device, 500, 101);
8015     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8016     color = getPixelColor(device, 504, 101);
8017     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8018     color = getPixelColor(device, 500, 105);
8019     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8020     color = getPixelColor(device, 504, 105);
8021     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8022
8023     color = getPixelColor(device, 500, 376);
8024     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8025     color = getPixelColor(device, 504, 376);
8026     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8027     color = getPixelColor(device, 500, 380);
8028     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8029     color = getPixelColor(device, 504, 380);
8030     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8031
8032     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8033
8034     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8035     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8036     IDirect3DTexture9_Release(texture);
8037 }
8038
8039 static void vFace_register_test(IDirect3DDevice9 *device)
8040 {
8041     HRESULT hr;
8042     DWORD color;
8043     const DWORD shader_code[] = {
8044         0xffff0300,                                                             /* ps_3_0                     */
8045         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8046         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8047         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8048         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8049         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8050         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8051         0x0000ffff                                                              /* END                        */
8052     };
8053     IDirect3DPixelShader9 *shader;
8054     IDirect3DTexture9 *texture;
8055     IDirect3DSurface9 *surface, *backbuffer;
8056     const float quad[] = {
8057         -1.0,   -1.0,   0.1,
8058          1.0,   -1.0,   0.1,
8059         -1.0,    0.0,   0.1,
8060
8061          1.0,   -1.0,   0.1,
8062          1.0,    0.0,   0.1,
8063         -1.0,    0.0,   0.1,
8064
8065         -1.0,    0.0,   0.1,
8066         -1.0,    1.0,   0.1,
8067          1.0,    0.0,   0.1,
8068
8069          1.0,    0.0,   0.1,
8070         -1.0,    1.0,   0.1,
8071          1.0,    1.0,   0.1,
8072     };
8073     const float blit[] = {
8074          0.0,   -1.0,   0.1,    0.0,    0.0,
8075          1.0,   -1.0,   0.1,    1.0,    0.0,
8076          0.0,    1.0,   0.1,    0.0,    1.0,
8077          1.0,    1.0,   0.1,    1.0,    1.0,
8078     };
8079
8080     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8081     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8082     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8083     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8084     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8085     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8086     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8087     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8088     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8089     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8090     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8091     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8092
8093     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8094     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8095
8096     hr = IDirect3DDevice9_BeginScene(device);
8097     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8098     if(SUCCEEDED(hr)) {
8099         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8100         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8101         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8102         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8103         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8104         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8105         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8106         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8107         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8108         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8109         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8110
8111         /* Blit the texture onto the back buffer to make it visible */
8112         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8113         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8114         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8115         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8116         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8117         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8118         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8119         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8120         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8121         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8122
8123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8124         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8125
8126         hr = IDirect3DDevice9_EndScene(device);
8127         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8128     }
8129
8130     color = getPixelColor(device, 160, 360);
8131     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8132     color = getPixelColor(device, 160, 120);
8133     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8134     color = getPixelColor(device, 480, 360);
8135     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8136     color = getPixelColor(device, 480, 120);
8137     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8138     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8139
8140     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8141     IDirect3DDevice9_SetTexture(device, 0, NULL);
8142     IDirect3DPixelShader9_Release(shader);
8143     IDirect3DSurface9_Release(surface);
8144     IDirect3DSurface9_Release(backbuffer);
8145     IDirect3DTexture9_Release(texture);
8146 }
8147
8148 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8149 {
8150     HRESULT hr;
8151     DWORD color;
8152     int i;
8153     D3DCAPS9 caps;
8154     BOOL L6V5U5_supported = FALSE;
8155     IDirect3DTexture9 *tex1, *tex2;
8156     D3DLOCKED_RECT locked_rect;
8157
8158     static const float quad[][7] = {
8159         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8160         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8161         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8162         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8163     };
8164
8165     static const D3DVERTEXELEMENT9 decl_elements[] = {
8166         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8167         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8168         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8169         D3DDECL_END()
8170     };
8171
8172     /* use asymmetric matrix to test loading */
8173     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8174     float scale, offset;
8175
8176     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8177     IDirect3DTexture9           *texture            = NULL;
8178
8179     memset(&caps, 0, sizeof(caps));
8180     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8181     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8182     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8183         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8184         return;
8185     } else {
8186         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8187          * They report that it is not supported, but after that bump mapping works properly. So just test
8188          * if the format is generally supported, and check the BUMPENVMAP flag
8189          */
8190         IDirect3D9 *d3d9;
8191
8192         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8193         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8194                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8195         L6V5U5_supported = SUCCEEDED(hr);
8196         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8197                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8198         IDirect3D9_Release(d3d9);
8199         if(FAILED(hr)) {
8200             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8201             return;
8202         }
8203     }
8204
8205     /* Generate the textures */
8206     generate_bumpmap_textures(device);
8207
8208     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8209     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8210     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8211     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8212     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8213     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8214     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8215     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8216
8217     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8218     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8219     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8220     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8221     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8222     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8223
8224     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8225     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8226     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8227     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8228     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8229     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8230
8231     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8232     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8233
8234     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8235     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8236
8237     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8238     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8239
8240
8241     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8242     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8243     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8244     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8245
8246     hr = IDirect3DDevice9_BeginScene(device);
8247     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8248
8249     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8250     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8251
8252     hr = IDirect3DDevice9_EndScene(device);
8253     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8254
8255     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8256      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8257      * But since testing the color match is not the purpose of the test don't be too picky
8258      */
8259     color = getPixelColor(device, 320-32, 240);
8260     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8261     color = getPixelColor(device, 320+32, 240);
8262     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8263     color = getPixelColor(device, 320, 240-32);
8264     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8265     color = getPixelColor(device, 320, 240+32);
8266     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8267     color = getPixelColor(device, 320, 240);
8268     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8269     color = getPixelColor(device, 320+32, 240+32);
8270     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8271     color = getPixelColor(device, 320-32, 240+32);
8272     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8273     color = getPixelColor(device, 320+32, 240-32);
8274     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8275     color = getPixelColor(device, 320-32, 240-32);
8276     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8277     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8278     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8279
8280     for(i = 0; i < 2; i++) {
8281         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8282         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8283         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8284         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8285         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8286         IDirect3DTexture9_Release(texture); /* To destroy it */
8287     }
8288
8289     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8290         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8291         goto cleanup;
8292     }
8293     if(L6V5U5_supported == FALSE) {
8294         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8295         goto cleanup;
8296     }
8297
8298     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8299     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8300     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8301      * would only make this test more complicated
8302      */
8303     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8304     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8305     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8306     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8307
8308     memset(&locked_rect, 0, sizeof(locked_rect));
8309     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8310     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8311     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8312     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8313     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8314
8315     memset(&locked_rect, 0, sizeof(locked_rect));
8316     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8317     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8318     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8319     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8320     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8321
8322     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8323     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8324     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8325     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8326
8327     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8328     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8329     scale = 2.0;
8330     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8331     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8332     offset = 0.1;
8333     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8334     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8335
8336     hr = IDirect3DDevice9_BeginScene(device);
8337     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8338     if(SUCCEEDED(hr)) {
8339         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8340         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8341         hr = IDirect3DDevice9_EndScene(device);
8342         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8343     }
8344
8345     color = getPixelColor(device, 320, 240);
8346     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8347      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8348      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8349      */
8350     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8351     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8352     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8353
8354     /* Check a result scale factor > 1.0 */
8355     scale = 10;
8356     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8357     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8358     offset = 10;
8359     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8360     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8361
8362     hr = IDirect3DDevice9_BeginScene(device);
8363     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8364     if(SUCCEEDED(hr)) {
8365         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8366         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8367         hr = IDirect3DDevice9_EndScene(device);
8368         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8369     }
8370     color = getPixelColor(device, 320, 240);
8371     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8372     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8373     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8374
8375     /* Check clamping in the scale factor calculation */
8376     scale = 1000;
8377     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8378     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8379     offset = -1;
8380     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8381     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8382
8383     hr = IDirect3DDevice9_BeginScene(device);
8384     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8385     if(SUCCEEDED(hr)) {
8386         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8387         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8388         hr = IDirect3DDevice9_EndScene(device);
8389         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8390     }
8391     color = getPixelColor(device, 320, 240);
8392     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8393     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8394     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8395
8396     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8397     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8398     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8400
8401     IDirect3DTexture9_Release(tex1);
8402     IDirect3DTexture9_Release(tex2);
8403
8404 cleanup:
8405     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8406     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8407     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8408     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8409
8410     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8411     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8412     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8413 }
8414
8415 static void stencil_cull_test(IDirect3DDevice9 *device) {
8416     HRESULT hr;
8417     IDirect3DSurface9 *depthstencil = NULL;
8418     D3DSURFACE_DESC desc;
8419     float quad1[] = {
8420         -1.0,   -1.0,   0.1,
8421          0.0,   -1.0,   0.1,
8422         -1.0,    0.0,   0.1,
8423          0.0,    0.0,   0.1,
8424     };
8425     float quad2[] = {
8426          0.0,   -1.0,   0.1,
8427          1.0,   -1.0,   0.1,
8428          0.0,    0.0,   0.1,
8429          1.0,    0.0,   0.1,
8430     };
8431     float quad3[] = {
8432         0.0,    0.0,   0.1,
8433         1.0,    0.0,   0.1,
8434         0.0,    1.0,   0.1,
8435         1.0,    1.0,   0.1,
8436     };
8437     float quad4[] = {
8438         -1.0,    0.0,   0.1,
8439          0.0,    0.0,   0.1,
8440         -1.0,    1.0,   0.1,
8441          0.0,    1.0,   0.1,
8442     };
8443     struct vertex painter[] = {
8444        {-1.0,   -1.0,   0.0,    0x00000000},
8445        { 1.0,   -1.0,   0.0,    0x00000000},
8446        {-1.0,    1.0,   0.0,    0x00000000},
8447        { 1.0,    1.0,   0.0,    0x00000000},
8448     };
8449     WORD indices_cw[]  = {0, 1, 3};
8450     WORD indices_ccw[] = {0, 2, 3};
8451     unsigned int i;
8452     DWORD color;
8453
8454     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8455     if(depthstencil == NULL) {
8456         skip("No depth stencil buffer\n");
8457         return;
8458     }
8459     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8460     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8461     IDirect3DSurface9_Release(depthstencil);
8462     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8463         skip("No 4 or 8 bit stencil surface\n");
8464         return;
8465     }
8466
8467     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8468     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8469     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8470
8471     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8472     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8473     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8474     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8475     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8476     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8477     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8478     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8479
8480     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8481     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8484     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8485     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8486
8487     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8488     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8489     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8490     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8491
8492     /* First pass: Fill the stencil buffer with some values... */
8493     hr = IDirect3DDevice9_BeginScene(device);
8494     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8495     if(SUCCEEDED(hr))
8496     {
8497         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8498         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8499         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8500                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8501         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8502         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8503                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8504         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8505
8506         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8507         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8508         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8509         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8510         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8511                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8512         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8513         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8514                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8515         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8516
8517         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8518         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8519         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8520                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8521         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8522         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8523                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8524         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8525
8526         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8527         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8528         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8529                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8530         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8531         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8532                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8533         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8534
8535         hr = IDirect3DDevice9_EndScene(device);
8536         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8537     }
8538
8539     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8540     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8541     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8542     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8543     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8544     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8545     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8548     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8550     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8551     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8552
8553     /* 2nd pass: Make the stencil values visible */
8554     hr = IDirect3DDevice9_BeginScene(device);
8555     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8556     if(SUCCEEDED(hr))
8557     {
8558         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8559         for(i = 0; i < 16; i++) {
8560             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8561             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8562
8563             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8564             painter[1].diffuse = (i * 16);
8565             painter[2].diffuse = (i * 16);
8566             painter[3].diffuse = (i * 16);
8567             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8568             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8569         }
8570         hr = IDirect3DDevice9_EndScene(device);
8571         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8572     }
8573
8574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576
8577     color = getPixelColor(device, 160, 420);
8578     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8579     color = getPixelColor(device, 160, 300);
8580     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8581
8582     color = getPixelColor(device, 480, 420);
8583     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8584     color = getPixelColor(device, 480, 300);
8585     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8586
8587     color = getPixelColor(device, 160, 180);
8588     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8589     color = getPixelColor(device, 160, 60);
8590     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8591
8592     color = getPixelColor(device, 480, 180);
8593     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8594     color = getPixelColor(device, 480, 60);
8595     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8596
8597     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8598     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8599 }
8600
8601 static void vpos_register_test(IDirect3DDevice9 *device)
8602 {
8603     HRESULT hr;
8604     DWORD color;
8605     const DWORD shader_code[] = {
8606     0xffff0300,                                                             /* ps_3_0                     */
8607     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8608     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8609     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8610     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8611     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8612     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8613     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8614     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8615     0x0000ffff                                                              /* end                        */
8616     };
8617     const DWORD shader_frac_code[] = {
8618     0xffff0300,                                                             /* ps_3_0                     */
8619     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8620     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8621     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8622     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8623     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8624     0x0000ffff                                                              /* end                        */
8625     };
8626     IDirect3DPixelShader9 *shader, *shader_frac;
8627     IDirect3DSurface9 *surface = NULL, *backbuffer;
8628     const float quad[] = {
8629         -1.0,   -1.0,   0.1,    0.0,    0.0,
8630          1.0,   -1.0,   0.1,    1.0,    0.0,
8631         -1.0,    1.0,   0.1,    0.0,    1.0,
8632          1.0,    1.0,   0.1,    1.0,    1.0,
8633     };
8634     D3DLOCKED_RECT lr;
8635     float constant[4] = {1.0, 0.0, 320, 240};
8636     DWORD *pos;
8637
8638     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8639     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8640     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8641     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8642     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8643     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8644     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8645     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8646     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8648     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8649     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8650
8651     hr = IDirect3DDevice9_BeginScene(device);
8652     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8653     if(SUCCEEDED(hr)) {
8654         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8655         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8656         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8657         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8658         hr = IDirect3DDevice9_EndScene(device);
8659         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8660     }
8661
8662     /* This has to be pixel exact */
8663     color = getPixelColor(device, 319, 239);
8664     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8665     color = getPixelColor(device, 320, 239);
8666     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8667     color = getPixelColor(device, 319, 240);
8668     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8669     color = getPixelColor(device, 320, 240);
8670     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8671     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8672
8673     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8674                                              &surface, NULL);
8675     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8676     hr = IDirect3DDevice9_BeginScene(device);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8678     if(SUCCEEDED(hr)) {
8679         constant[2] = 16; constant[3] = 16;
8680         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8681         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8682         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8683         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8684         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8685         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8686         hr = IDirect3DDevice9_EndScene(device);
8687         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8688     }
8689     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8690     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8691
8692     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8693     color = *pos & 0x00ffffff;
8694     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8695     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8696     color = *pos & 0x00ffffff;
8697     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8698     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8699     color = *pos & 0x00ffffff;
8700     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8701     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8702     color = *pos & 0x00ffffff;
8703     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8704
8705     hr = IDirect3DSurface9_UnlockRect(surface);
8706     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8707
8708     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8709      * have full control over the multisampling setting inside this test
8710      */
8711     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8712     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8713     hr = IDirect3DDevice9_BeginScene(device);
8714     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8715     if(SUCCEEDED(hr)) {
8716         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8717         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8718         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8719         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8720         hr = IDirect3DDevice9_EndScene(device);
8721         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8722     }
8723     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8724     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8725
8726     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8727     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8728
8729     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8730     color = *pos & 0x00ffffff;
8731     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8732
8733     hr = IDirect3DSurface9_UnlockRect(surface);
8734     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8735
8736     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8738     IDirect3DPixelShader9_Release(shader);
8739     IDirect3DPixelShader9_Release(shader_frac);
8740     if(surface) IDirect3DSurface9_Release(surface);
8741     IDirect3DSurface9_Release(backbuffer);
8742 }
8743
8744 static void pointsize_test(IDirect3DDevice9 *device)
8745 {
8746     HRESULT hr;
8747     D3DCAPS9 caps;
8748     D3DMATRIX matrix;
8749     D3DMATRIX identity;
8750     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8751     DWORD color;
8752     IDirect3DTexture9 *tex1, *tex2;
8753     D3DLOCKED_RECT lr;
8754     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8755                                 0x00000000, 0x00000000};
8756     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8757                                 0x00000000, 0x0000ff00};
8758
8759     const float vertices[] = {
8760         64,     64,     0.1,
8761         128,    64,     0.1,
8762         192,    64,     0.1,
8763         256,    64,     0.1,
8764         320,    64,     0.1,
8765         384,    64,     0.1,
8766         448,    64,     0.1,
8767         512,    64,     0.1,
8768         576,    64,     0.1,
8769     };
8770
8771     /* 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 */
8772     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;
8773     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;
8774     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;
8775     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;
8776
8777     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;
8778     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;
8779     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;
8780     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;
8781
8782     memset(&caps, 0, sizeof(caps));
8783     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8784     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8785     if(caps.MaxPointSize < 32.0) {
8786         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8787         return;
8788     }
8789
8790     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8791     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8792     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8793     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8794     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8795     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8796     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8797     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8798
8799     hr = IDirect3DDevice9_BeginScene(device);
8800     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8801     if(SUCCEEDED(hr)) {
8802         ptsize = 16.0;
8803         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8804         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8805         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8806         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8807
8808         ptsize = 32.0;
8809         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8810         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8811         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8813
8814         ptsize = 31.5;
8815         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8816         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8817         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8818         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8819
8820         if(caps.MaxPointSize >= 64.0) {
8821             ptsize = 64.0;
8822             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8823             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8824             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8825             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8826
8827             ptsize = 63.75;
8828             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8829             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8830             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8831             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8832         }
8833
8834         ptsize = 1.0;
8835         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8836         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8837         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8838         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8839
8840         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8841         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8842         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8843         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8844
8845         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8846         ptsize = 16.0;
8847         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8848         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8849         ptsize = 1.0;
8850         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8851         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8852         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8853         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8854
8855         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8856          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8857          */
8858         ptsize = 4.0;
8859         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8860         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8861         ptsize = 16.0;
8862         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8863         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8864         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8865         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8866
8867         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8868         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8869
8870         /* pointsize < pointsize_min < pointsize_max?
8871          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8872          */
8873         ptsize = 1.0;
8874         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8875         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8876         ptsize = 16.0;
8877         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8878         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8879         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8880         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8881
8882         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8883         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8884
8885         hr = IDirect3DDevice9_EndScene(device);
8886         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8887     }
8888     color = getPixelColor(device, 64-9, 64-9);
8889     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8890     color = getPixelColor(device, 64-8, 64-8);
8891     ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8892     color = getPixelColor(device, 64-7, 64-7);
8893     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8894     color = getPixelColor(device, 64+7, 64+7);
8895     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8896     color = getPixelColor(device, 64+8, 64+8);
8897     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8898     color = getPixelColor(device, 64+9, 64+9);
8899     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8900
8901     color = getPixelColor(device, 128-17, 64-17);
8902     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8903     color = getPixelColor(device, 128-16, 64-16);
8904     ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8905     color = getPixelColor(device, 128-15, 64-15);
8906     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8907     color = getPixelColor(device, 128+15, 64+15);
8908     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8909     color = getPixelColor(device, 128+16, 64+16);
8910     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8911     color = getPixelColor(device, 128+17, 64+17);
8912     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8913
8914     color = getPixelColor(device, 192-17, 64-17);
8915     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8916     color = getPixelColor(device, 192-16, 64-16);
8917     todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8918     color = getPixelColor(device, 192-15, 64-15);
8919     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8920     color = getPixelColor(device, 192+15, 64+15);
8921     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8922     color = getPixelColor(device, 192+16, 64+16);
8923     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8924     color = getPixelColor(device, 192+17, 64+17);
8925     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8926
8927     if(caps.MaxPointSize >= 64.0) {
8928         color = getPixelColor(device, 256-33, 64-33);
8929         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8930         color = getPixelColor(device, 256-32, 64-32);
8931         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8932         color = getPixelColor(device, 256-31, 64-31);
8933         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8934         color = getPixelColor(device, 256+31, 64+31);
8935         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8936         color = getPixelColor(device, 256+32, 64+32);
8937         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8938         color = getPixelColor(device, 256+33, 64+33);
8939         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8940
8941         color = getPixelColor(device, 384-33, 64-33);
8942         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8943         color = getPixelColor(device, 384-32, 64-32);
8944         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8945         color = getPixelColor(device, 384-31, 64-31);
8946         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8947         color = getPixelColor(device, 384+31, 64+31);
8948         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8949         color = getPixelColor(device, 384+32, 64+32);
8950         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8951         color = getPixelColor(device, 384+33, 64+33);
8952         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8953     }
8954
8955     color = getPixelColor(device, 320-1, 64-1);
8956     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8957     color = getPixelColor(device, 320-0, 64-0);
8958     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8959     color = getPixelColor(device, 320+1, 64+1);
8960     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8961
8962     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8963     color = getPixelColor(device, 448-4, 64-4);
8964     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8965     color = getPixelColor(device, 448+4, 64+4);
8966     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8967
8968     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8969     color = getPixelColor(device, 512-4, 64-4);
8970     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8971     color = getPixelColor(device, 512+4, 64+4);
8972     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8973
8974     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8975      * Don't be overly picky - just show that the point is bigger than 1 pixel
8976      */
8977     color = getPixelColor(device, 576-4, 64-4);
8978     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8979     color = getPixelColor(device, 576+4, 64+4);
8980     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8981
8982     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8983
8984     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8985      * generates texture coordinates for the point(result: Yes, it does)
8986      *
8987      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8988      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8989      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8990      */
8991     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8992     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8993
8994     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8995     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8996     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8997     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8998     memset(&lr, 0, sizeof(lr));
8999     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
9000     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9001     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
9002     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9003     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9004     memset(&lr, 0, sizeof(lr));
9005     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
9006     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9007     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
9008     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9009     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9010     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9011     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9012     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9013     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9014     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9015     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9016     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9017     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9018     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9019     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9020     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9021     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9022     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9023     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9024
9025     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
9026     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9027     ptsize = 32.0;
9028     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
9029     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
9030
9031     hr = IDirect3DDevice9_BeginScene(device);
9032     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9033     if(SUCCEEDED(hr))
9034     {
9035         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9036         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9037         hr = IDirect3DDevice9_EndScene(device);
9038         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9039     }
9040
9041     color = getPixelColor(device, 64-4, 64-4);
9042     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9043     color = getPixelColor(device, 64-4, 64+4);
9044     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9045     color = getPixelColor(device, 64+4, 64+4);
9046     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9047     color = getPixelColor(device, 64+4, 64-4);
9048     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9049     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9050
9051     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9052     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9053     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9054     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9055     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9056     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9057     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9058     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9059     IDirect3DTexture9_Release(tex1);
9060     IDirect3DTexture9_Release(tex2);
9061
9062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9065     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9066     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9068 }
9069
9070 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9071 {
9072     HRESULT hr;
9073     IDirect3DPixelShader9 *ps;
9074     IDirect3DTexture9 *tex1, *tex2;
9075     IDirect3DSurface9 *surf1, *surf2, *backbuf;
9076     D3DCAPS9 caps;
9077     DWORD color;
9078     DWORD shader_code[] = {
9079     0xffff0300,                                                             /* ps_3_0             */
9080     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9081     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9082     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
9083     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
9084     0x0000ffff                                                              /* END                */
9085     };
9086     float quad[] = {
9087        -1.0,   -1.0,    0.1,
9088         1.0,   -1.0,    0.1,
9089        -1.0,    1.0,    0.1,
9090         1.0,    1.0,    0.1,
9091     };
9092     float texquad[] = {
9093        -1.0,   -1.0,    0.1,    0.0,    0.0,
9094         0.0,   -1.0,    0.1,    1.0,    0.0,
9095        -1.0,    1.0,    0.1,    0.0,    1.0,
9096         0.0,    1.0,    0.1,    1.0,    1.0,
9097
9098         0.0,   -1.0,    0.1,    0.0,    0.0,
9099         1.0,   -1.0,    0.1,    1.0,    0.0,
9100         0.0,    1.0,    0.1,    0.0,    1.0,
9101         1.0,    1.0,    0.1,    1.0,    1.0,
9102     };
9103
9104     memset(&caps, 0, sizeof(caps));
9105     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9106     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9107     if(caps.NumSimultaneousRTs < 2) {
9108         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9109         return;
9110     }
9111
9112     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9113     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9114
9115     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9116     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9117     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9118     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9119     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9120     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9121
9122     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9123     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9124     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9125     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9126     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9127     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9128
9129     hr = IDirect3DDevice9_SetPixelShader(device, ps);
9130     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9131     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9132     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9133     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9134     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9135     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9136     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9137
9138     hr = IDirect3DDevice9_BeginScene(device);
9139     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9140     if(SUCCEEDED(hr)) {
9141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9142         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9143
9144         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9145         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9146         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9147         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9148         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9149         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9150         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9151         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9152
9153         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9154         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9157
9158         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9159         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9160         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9161         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9162
9163         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9164         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9165
9166         hr = IDirect3DDevice9_EndScene(device);
9167         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9168     }
9169
9170     color = getPixelColor(device, 160, 240);
9171     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9172     color = getPixelColor(device, 480, 240);
9173     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9174     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9175
9176     IDirect3DPixelShader9_Release(ps);
9177     IDirect3DTexture9_Release(tex1);
9178     IDirect3DTexture9_Release(tex2);
9179     IDirect3DSurface9_Release(surf1);
9180     IDirect3DSurface9_Release(surf2);
9181     IDirect3DSurface9_Release(backbuf);
9182 }
9183
9184 struct formats {
9185     const char *fmtName;
9186     D3DFORMAT textureFormat;
9187     DWORD resultColorBlending;
9188     DWORD resultColorNoBlending;
9189 };
9190
9191 const struct formats test_formats[] = {
9192   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9193   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9194   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9195   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9196   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9197   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9198   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9199   { NULL, 0 }
9200 };
9201
9202 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9203 {
9204     HRESULT hr;
9205     IDirect3DTexture9 *offscreenTexture = NULL;
9206     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9207     IDirect3D9 *d3d = NULL;
9208     DWORD color;
9209     DWORD r0, g0, b0, r1, g1, b1;
9210     int fmt_index;
9211
9212     static const float quad[][5] = {
9213         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9214         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9215         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9216         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9217     };
9218
9219     /* Quad with R=0x10, G=0x20 */
9220     static const struct vertex quad1[] = {
9221         {-1.0f, -1.0f, 0.1f, 0x80102000},
9222         {-1.0f,  1.0f, 0.1f, 0x80102000},
9223         { 1.0f, -1.0f, 0.1f, 0x80102000},
9224         { 1.0f,  1.0f, 0.1f, 0x80102000},
9225     };
9226
9227     /* Quad with R=0x20, G=0x10 */
9228     static const struct vertex quad2[] = {
9229         {-1.0f, -1.0f, 0.1f, 0x80201000},
9230         {-1.0f,  1.0f, 0.1f, 0x80201000},
9231         { 1.0f, -1.0f, 0.1f, 0x80201000},
9232         { 1.0f,  1.0f, 0.1f, 0x80201000},
9233     };
9234
9235     IDirect3DDevice9_GetDirect3D(device, &d3d);
9236
9237     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9238     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9239     if(!backbuffer) {
9240         goto out;
9241     }
9242
9243     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9244     {
9245         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9246         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9247            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9248            continue;
9249         }
9250
9251         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9252         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9253
9254         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9255         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9256         if(!offscreenTexture) {
9257             continue;
9258         }
9259
9260         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9261         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9262         if(!offscreen) {
9263             continue;
9264         }
9265
9266         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9267         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9268
9269         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9270         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9271         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9272         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9273         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9274         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9275         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9276         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9277         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9278         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9279
9280         /* Below we will draw two quads with different colors and try to blend them together.
9281          * The result color is compared with the expected outcome.
9282          */
9283         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9284             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9285             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9286             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9287             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9288
9289             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9290             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9291
9292             /* Draw a quad using color 0x0010200 */
9293             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9294             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9295             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9296             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9297             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9298             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9299
9300             /* Draw a quad using color 0x0020100 */
9301             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9302             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9303             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9304             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9305             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9306             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9307
9308             /* We don't want to blend the result on the backbuffer */
9309             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9310             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9311
9312             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9313             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9314             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9315             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9316             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9317
9318             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9319             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9320
9321             /* This time with the texture */
9322             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9323             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9324
9325             IDirect3DDevice9_EndScene(device);
9326         }
9327
9328         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9329             /* Compare the color of the center quad with our expectation */
9330             color = getPixelColor(device, 320, 240);
9331             r0 = (color & 0x00ff0000) >> 16;
9332             g0 = (color & 0x0000ff00) >>  8;
9333             b0 = (color & 0x000000ff) >>  0;
9334
9335             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9336             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9337             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9338
9339             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9340                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9341                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9342                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9343         } else {
9344             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9345              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9346              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9347             color = getPixelColor(device, 320, 240);
9348             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);
9349         }
9350         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9351
9352         IDirect3DDevice9_SetTexture(device, 0, NULL);
9353         if(offscreenTexture) {
9354             IDirect3DTexture9_Release(offscreenTexture);
9355         }
9356         if(offscreen) {
9357             IDirect3DSurface9_Release(offscreen);
9358         }
9359     }
9360
9361 out:
9362     /* restore things */
9363     if(backbuffer) {
9364         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9365         IDirect3DSurface9_Release(backbuffer);
9366     }
9367 }
9368
9369 static void tssargtemp_test(IDirect3DDevice9 *device)
9370 {
9371     HRESULT hr;
9372     DWORD color;
9373     static const struct vertex quad[] = {
9374         {-1.0,     -1.0,    0.1,    0x00ff0000},
9375         { 1.0,     -1.0,    0.1,    0x00ff0000},
9376         {-1.0,      1.0,    0.1,    0x00ff0000},
9377         { 1.0,      1.0,    0.1,    0x00ff0000}
9378     };
9379     D3DCAPS9 caps;
9380
9381     memset(&caps, 0, sizeof(caps));
9382     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9383     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9384     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9385         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9386         return;
9387     }
9388
9389     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9390     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9391
9392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9393     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9395     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9396
9397     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9398     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9399     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9400     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9401     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9402     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9403
9404     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9405     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9406     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9407     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9408     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9409     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9410
9411     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9412     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9413
9414     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9415     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9416     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9417     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9418
9419     hr = IDirect3DDevice9_BeginScene(device);
9420     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9421     if(SUCCEEDED(hr)) {
9422         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9423         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9424         hr = IDirect3DDevice9_EndScene(device);
9425         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9426     }
9427     color = getPixelColor(device, 320, 240);
9428     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9429     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9430
9431     /* Set stage 1 back to default */
9432     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9433     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9434     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9435     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9436     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9437     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9438     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9439     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9440     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9441     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9442 }
9443
9444 struct testdata
9445 {
9446     DWORD idxVertex; /* number of instances in the first stream */
9447     DWORD idxColor; /* number of instances in the second stream */
9448     DWORD idxInstance; /* should be 1 ?? */
9449     DWORD color1; /* color 1 instance */
9450     DWORD color2; /* color 2 instance */
9451     DWORD color3; /* color 3 instance */
9452     DWORD color4; /* color 4 instance */
9453     WORD strVertex; /* specify which stream to use 0-2*/
9454     WORD strColor;
9455     WORD strInstance;
9456 };
9457
9458 static const struct testdata testcases[]=
9459 {
9460     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9461     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9462     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9463     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9464     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9465     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9466     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9467     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9468     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9469     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9470     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9471     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9472     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9473     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9474     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9475 /*
9476     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9477     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9478 */
9479 };
9480
9481 /* Drawing Indexed Geometry with instances*/
9482 static void stream_test(IDirect3DDevice9 *device)
9483 {
9484     IDirect3DVertexBuffer9 *vb = NULL;
9485     IDirect3DVertexBuffer9 *vb2 = NULL;
9486     IDirect3DVertexBuffer9 *vb3 = NULL;
9487     IDirect3DIndexBuffer9 *ib = NULL;
9488     IDirect3DVertexDeclaration9 *pDecl = NULL;
9489     IDirect3DVertexShader9 *shader = NULL;
9490     HRESULT hr;
9491     BYTE *data;
9492     DWORD color;
9493     DWORD ind;
9494     unsigned i;
9495
9496     const DWORD shader_code[] =
9497     {
9498         0xfffe0101,                                     /* vs_1_1 */
9499         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9500         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9501         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9502         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9503         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9504         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9505         0x0000ffff
9506     };
9507
9508     const float quad[][3] =
9509     {
9510         {-0.5f, -0.5f,  1.1f}, /*0 */
9511         {-0.5f,  0.5f,  1.1f}, /*1 */
9512         { 0.5f, -0.5f,  1.1f}, /*2 */
9513         { 0.5f,  0.5f,  1.1f}, /*3 */
9514     };
9515
9516     const float vertcolor[][4] =
9517     {
9518         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9519         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9520         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9521         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9522     };
9523
9524     /* 4 position for 4 instances */
9525     const float instancepos[][3] =
9526     {
9527         {-0.6f,-0.6f, 0.0f},
9528         { 0.6f,-0.6f, 0.0f},
9529         { 0.6f, 0.6f, 0.0f},
9530         {-0.6f, 0.6f, 0.0f},
9531     };
9532
9533     short indices[] = {0, 1, 2, 1, 2, 3};
9534
9535     D3DVERTEXELEMENT9 decl[] =
9536     {
9537         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9538         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9539         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9540         D3DDECL_END()
9541     };
9542
9543     /* set the default value because it isn't done in wine? */
9544     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9545     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9546
9547     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9548     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9549     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9550
9551     /* check wrong cases */
9552     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9553     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9554     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9555     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9556     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9557     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9558     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9559     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9560     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9561     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9562     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9563     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9564     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9565     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9566     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9567     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9568     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9569     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9570     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9571     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9572
9573     /* set the default value back */
9574     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9575     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9576
9577     /* create all VertexBuffers*/
9578     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9579     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9580     if(!vb) {
9581         skip("Failed to create a vertex buffer\n");
9582         return;
9583     }
9584     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9585     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9586     if(!vb2) {
9587         skip("Failed to create a vertex buffer\n");
9588         goto out;
9589     }
9590     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9591     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9592     if(!vb3) {
9593         skip("Failed to create a vertex buffer\n");
9594         goto out;
9595     }
9596
9597     /* create IndexBuffer*/
9598     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9599     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9600     if(!ib) {
9601         skip("Failed to create a index buffer\n");
9602         goto out;
9603     }
9604
9605     /* copy all Buffers (Vertex + Index)*/
9606     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9607     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9608     memcpy(data, quad, sizeof(quad));
9609     hr = IDirect3DVertexBuffer9_Unlock(vb);
9610     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9611     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9612     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9613     memcpy(data, vertcolor, sizeof(vertcolor));
9614     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9615     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9616     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9617     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9618     memcpy(data, instancepos, sizeof(instancepos));
9619     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9620     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9621     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9622     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9623     memcpy(data, indices, sizeof(indices));
9624     hr = IDirect3DIndexBuffer9_Unlock(ib);
9625     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9626
9627     /* create VertexShader */
9628     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9629     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9630     if(!shader) {
9631         skip("Failed to create a vetex shader\n");
9632         goto out;
9633     }
9634
9635     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9637
9638     hr = IDirect3DDevice9_SetIndices(device, ib);
9639     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9640
9641     /* run all tests */
9642     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9643     {
9644         struct testdata act = testcases[i];
9645         decl[0].Stream = act.strVertex;
9646         decl[1].Stream = act.strColor;
9647         decl[2].Stream = act.strInstance;
9648         /* create VertexDeclarations */
9649         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9650         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9651
9652         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9653         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9654
9655         hr = IDirect3DDevice9_BeginScene(device);
9656         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9657         if(SUCCEEDED(hr))
9658         {
9659             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9660             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9661
9662             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9663             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9664             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9665             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9666
9667             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9668             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9669             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9670             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9671
9672             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9673             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9674             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9675             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9676
9677             /* don't know if this is right (1*3 and 4*1)*/
9678             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9679             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9680             hr = IDirect3DDevice9_EndScene(device);
9681             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9682
9683             /* set all StreamSource && StreamSourceFreq back to default */
9684             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9685             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9686             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9687             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9688             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9689             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9690             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9691             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9692             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9693             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9694             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9695             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9696         }
9697
9698         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9699         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9700
9701         color = getPixelColor(device, 160, 360);
9702         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9703         color = getPixelColor(device, 480, 360);
9704         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9705         color = getPixelColor(device, 480, 120);
9706         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9707         color = getPixelColor(device, 160, 120);
9708         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9709
9710         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9711         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9712     }
9713
9714     hr = IDirect3DDevice9_SetIndices(device, NULL);
9715     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9716
9717 out:
9718     if(vb) IDirect3DVertexBuffer9_Release(vb);
9719     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9720     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9721     if(ib)IDirect3DIndexBuffer9_Release(ib);
9722     if(shader)IDirect3DVertexShader9_Release(shader);
9723 }
9724
9725 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9726     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9727     IDirect3DTexture9 *dsttex = NULL;
9728     HRESULT hr;
9729     DWORD color;
9730     D3DRECT r1 = {0,  0,  50,  50 };
9731     D3DRECT r2 = {50, 0,  100, 50 };
9732     D3DRECT r3 = {50, 50, 100, 100};
9733     D3DRECT r4 = {0,  50,  50, 100};
9734     const float quad[] = {
9735         -1.0,   -1.0,   0.1,    0.0,    0.0,
9736          1.0,   -1.0,   0.1,    1.0,    0.0,
9737         -1.0,    1.0,   0.1,    0.0,    1.0,
9738          1.0,    1.0,   0.1,    1.0,    1.0,
9739     };
9740
9741     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9742     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9743
9744     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9745     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9746     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9747     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9748
9749     if(!src || !dsttex) {
9750         skip("One or more test resources could not be created\n");
9751         goto cleanup;
9752     }
9753
9754     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9755     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9756
9757     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9758     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9759
9760     /* Clear the StretchRect destination for debugging */
9761     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9762     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9763     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9764     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9765
9766     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9767     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9768
9769     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9770     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9771     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9772     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9773     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9774     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9775     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9776     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9777
9778     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9779      * the target -> texture GL blit path
9780      */
9781     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9782     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9783     IDirect3DSurface9_Release(dst);
9784
9785     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9786     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9787
9788     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9789     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9790     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9791     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9792     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9793     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9794     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9795     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9796
9797     hr = IDirect3DDevice9_BeginScene(device);
9798     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9799     if(SUCCEEDED(hr)) {
9800         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9801         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9802         hr = IDirect3DDevice9_EndScene(device);
9803         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9804     }
9805
9806     color = getPixelColor(device, 160, 360);
9807     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9808     color = getPixelColor(device, 480, 360);
9809     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9810     color = getPixelColor(device, 480, 120);
9811     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9812     color = getPixelColor(device, 160, 120);
9813     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9814     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9815     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9816
9817     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9818     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9819     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9820     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9821
9822 cleanup:
9823     if(src) IDirect3DSurface9_Release(src);
9824     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9825     if(dsttex) IDirect3DTexture9_Release(dsttex);
9826 }
9827
9828 static void texop_test(IDirect3DDevice9 *device)
9829 {
9830     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9831     IDirect3DTexture9 *texture = NULL;
9832     D3DLOCKED_RECT locked_rect;
9833     D3DCOLOR color;
9834     D3DCAPS9 caps;
9835     HRESULT hr;
9836     unsigned i;
9837
9838     static const struct {
9839         float x, y, z;
9840         float s, t;
9841         D3DCOLOR diffuse;
9842     } quad[] = {
9843         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9844         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9845         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9846         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9847     };
9848
9849     static const D3DVERTEXELEMENT9 decl_elements[] = {
9850         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9851         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9852         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9853         D3DDECL_END()
9854     };
9855
9856     static const struct {
9857         D3DTEXTUREOP op;
9858         const char *name;
9859         DWORD caps_flag;
9860         D3DCOLOR result;
9861     } test_data[] = {
9862         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9863         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9864         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9865         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9866         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9867         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9868         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9869         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9870         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9871         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9872         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9873         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9874         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9875         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9876         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9877         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9878         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9879         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9880         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9881         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9882         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9883         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9884         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9885     };
9886
9887     memset(&caps, 0, sizeof(caps));
9888     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9889     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9890
9891     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9892     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9893     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9894     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9895
9896     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9897     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9898     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9899     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9900     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9901     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9902     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9903     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9904     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9905
9906     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9907     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9908     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9909     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9910     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9911     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9912
9913     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9914     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9915
9916     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9917     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9918     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9919     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9921     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9922
9923     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9924     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9925
9926     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9927     {
9928         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9929         {
9930             skip("tex operation %s not supported\n", test_data[i].name);
9931             continue;
9932         }
9933
9934         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9935         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9936
9937         hr = IDirect3DDevice9_BeginScene(device);
9938         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9939
9940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9941         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9942
9943         hr = IDirect3DDevice9_EndScene(device);
9944         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9945
9946         color = getPixelColor(device, 320, 240);
9947         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9948                 test_data[i].name, color, test_data[i].result);
9949
9950         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9951         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9952     }
9953
9954     if (texture) IDirect3DTexture9_Release(texture);
9955     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9956 }
9957
9958 static void yuv_color_test(IDirect3DDevice9 *device) {
9959     HRESULT hr;
9960     IDirect3DSurface9 *surface = NULL, *target = NULL;
9961     unsigned int fmt, i;
9962     D3DFORMAT format;
9963     const char *fmt_string;
9964     D3DLOCKED_RECT lr;
9965     IDirect3D9 *d3d;
9966     HRESULT color;
9967     DWORD ref_color_left, ref_color_right;
9968
9969     struct {
9970         DWORD in;           /* The input color */
9971         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9972         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9973         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9974         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9975     } test_data[] = {
9976     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9977      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9978      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9979      * that
9980      */
9981       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9982       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9983       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9984       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9985       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9986       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9987       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9988       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9989       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9990       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9991       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9992       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9993       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9994       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9995
9996       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9997       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9998       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9999       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10000     };
10001
10002     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10003     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10004     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10005     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10006
10007     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10008     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10009
10010     for(fmt = 0; fmt < 2; fmt++) {
10011         if(fmt == 0) {
10012             format = D3DFMT_UYVY;
10013             fmt_string = "D3DFMT_UYVY";
10014         } else {
10015             format = D3DFMT_YUY2;
10016             fmt_string = "D3DFMT_YUY2";
10017         }
10018
10019         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10020                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10021                        */
10022         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10023                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10024             skip("%s is not supported\n", fmt_string);
10025             continue;
10026         }
10027
10028         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10029         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10030         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10031
10032         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10033             if(fmt == 0) {
10034                 ref_color_left = test_data[i].uyvy_left;
10035                 ref_color_right = test_data[i].uyvy_right;
10036             } else {
10037                 ref_color_left = test_data[i].yuy2_left;
10038                 ref_color_right = test_data[i].yuy2_right;
10039             }
10040
10041             memset(&lr, 0, sizeof(lr));
10042             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10043             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10044             *((DWORD *) lr.pBits) = test_data[i].in;
10045             hr = IDirect3DSurface9_UnlockRect(surface);
10046             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10047
10048             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10049             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10050             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10051             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10052
10053             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10054              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10055              * want to add tests for the filtered pixels as well.
10056              *
10057              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10058              * differently, so we need a max diff of 16
10059              */
10060             color = getPixelColor(device, 40, 240);
10061             ok(color_match(color, ref_color_left, 18),
10062                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10063                test_data[i].in, color, ref_color_left, fmt_string);
10064             color = getPixelColor(device, 600, 240);
10065             ok(color_match(color, ref_color_right, 18),
10066                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10067                test_data[i].in, color, ref_color_right, fmt_string);
10068             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10069             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10070         }
10071         IDirect3DSurface9_Release(surface);
10072     }
10073     IDirect3DSurface9_Release(target);
10074     IDirect3D9_Release(d3d);
10075 }
10076
10077 static void texop_range_test(IDirect3DDevice9 *device)
10078 {
10079     static const struct {
10080         float x, y, z;
10081         D3DCOLOR diffuse;
10082     } quad[] = {
10083         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10084         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10085         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10086         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10087     };
10088     HRESULT hr;
10089     IDirect3DTexture9 *texture;
10090     D3DLOCKED_RECT locked_rect;
10091     D3DCAPS9 caps;
10092     DWORD color;
10093
10094     /* We need ADD and SUBTRACT operations */
10095     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10096     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10097     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10098         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10099         return;
10100     }
10101     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10102         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10103         return;
10104     }
10105
10106     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10107     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10108     /* Stage 1: result = diffuse(=1.0) + diffuse
10109      * stage 2: result = result - tfactor(= 0.5)
10110      */
10111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10112     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10113     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10114     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10115     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10116     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10117     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10118     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10119     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10120     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10121     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10122     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10123     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10124     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10125
10126     hr = IDirect3DDevice9_BeginScene(device);
10127     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10128     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10129     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10130     hr = IDirect3DDevice9_EndScene(device);
10131     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10132
10133     color = getPixelColor(device, 320, 240);
10134     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10135        color);
10136     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10137     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10138
10139     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10140     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10141     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10142     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10143     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10144     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10145     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10146     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10147     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10148
10149     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10150      * stage 2: result = result + diffuse(1.0)
10151      */
10152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10153     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10154     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10155     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10156     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10157     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10158     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10159     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10160     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10161     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10162     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10163     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10164     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10165     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10166
10167     hr = IDirect3DDevice9_BeginScene(device);
10168     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10169     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10170     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10171     hr = IDirect3DDevice9_EndScene(device);
10172     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10173
10174     color = getPixelColor(device, 320, 240);
10175     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10176        color);
10177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10178     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10179
10180     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10181     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10182     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10183     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10184     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10185     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10186     IDirect3DTexture9_Release(texture);
10187 }
10188
10189 static void alphareplicate_test(IDirect3DDevice9 *device) {
10190     struct vertex quad[] = {
10191         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10192         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10193         { -1.0,     1.0,    0.1,    0x80ff00ff },
10194         {  1.0,     1.0,    0.1,    0x80ff00ff },
10195     };
10196     HRESULT hr;
10197     DWORD color;
10198
10199     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10200     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10201
10202     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10203     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10204
10205     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10206     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10207     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10208     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10209
10210     hr = IDirect3DDevice9_BeginScene(device);
10211     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10212     if(SUCCEEDED(hr)) {
10213         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10214         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10215         hr = IDirect3DDevice9_EndScene(device);
10216         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10217     }
10218
10219     color = getPixelColor(device, 320, 240);
10220     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10221        color);
10222     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10223     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10224
10225     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10226     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10227
10228 }
10229
10230 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10231     HRESULT hr;
10232     D3DCAPS9 caps;
10233     DWORD color;
10234     struct vertex quad[] = {
10235         { -1.0,    -1.0,    0.1,    0x408080c0 },
10236         {  1.0,    -1.0,    0.1,    0x408080c0 },
10237         { -1.0,     1.0,    0.1,    0x408080c0 },
10238         {  1.0,     1.0,    0.1,    0x408080c0 },
10239     };
10240
10241     memset(&caps, 0, sizeof(caps));
10242     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10243     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10244     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10245         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10246         return;
10247     }
10248
10249     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10250     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10251
10252     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10253     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10254
10255     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10256      * mov r0.a, diffuse.a
10257      * mov r0, r0.a
10258      *
10259      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10260      * 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
10261      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10262      */
10263     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10264     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10265     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10266     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10267     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10268     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10269     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10270     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10271     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10272     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10273     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10274     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10275     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10277     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10279     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10280     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10281
10282     hr = IDirect3DDevice9_BeginScene(device);
10283     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10284     if(SUCCEEDED(hr)) {
10285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10287         hr = IDirect3DDevice9_EndScene(device);
10288         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10289     }
10290
10291     color = getPixelColor(device, 320, 240);
10292     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10293        color);
10294     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10295     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10296
10297     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10298     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10299     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10300     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10301     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10302     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10303 }
10304
10305 static void zwriteenable_test(IDirect3DDevice9 *device) {
10306     HRESULT hr;
10307     DWORD color;
10308     struct vertex quad1[] = {
10309         { -1.0,  -1.0,  0.1,    0x00ff0000},
10310         { -1.0,   1.0,  0.1,    0x00ff0000},
10311         {  1.0,  -1.0,  0.1,    0x00ff0000},
10312         {  1.0,   1.0,  0.1,    0x00ff0000},
10313     };
10314     struct vertex quad2[] = {
10315         { -1.0,  -1.0,  0.9,    0x0000ff00},
10316         { -1.0,   1.0,  0.9,    0x0000ff00},
10317         {  1.0,  -1.0,  0.9,    0x0000ff00},
10318         {  1.0,   1.0,  0.9,    0x0000ff00},
10319     };
10320
10321     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10322     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10323
10324     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10325     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10326     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10327     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10328     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10329     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10330     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10331     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10332
10333     hr = IDirect3DDevice9_BeginScene(device);
10334     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10335     if(SUCCEEDED(hr)) {
10336         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10337          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10338          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10339          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10340          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10341          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10342          */
10343         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10344         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10345         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10346         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10347         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10348         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10349
10350         hr = IDirect3DDevice9_EndScene(device);
10351         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10352     }
10353
10354     color = getPixelColor(device, 320, 240);
10355     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10356        color);
10357     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10358     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10359
10360     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10361     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10362 }
10363
10364 static void alphatest_test(IDirect3DDevice9 *device) {
10365 #define ALPHATEST_PASSED 0x0000ff00
10366 #define ALPHATEST_FAILED 0x00ff0000
10367     struct {
10368         D3DCMPFUNC  func;
10369         DWORD       color_less;
10370         DWORD       color_equal;
10371         DWORD       color_greater;
10372     } testdata[] = {
10373         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10374         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10375         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10376         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10377         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10378         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10379         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10380         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10381     };
10382     unsigned int i, j;
10383     HRESULT hr;
10384     DWORD color;
10385     struct vertex quad[] = {
10386         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10387         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10388         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10389         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10390     };
10391     D3DCAPS9 caps;
10392
10393     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10394     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10395     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10396     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10397
10398     for(j = 0; j < 2; j++) {
10399         if(j == 1) {
10400             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10401              * the alpha test either for performance reasons(floating point RTs) or to work
10402              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10403              * codepath for ffp and shader in this case, and the test should cover both
10404              */
10405             IDirect3DPixelShader9 *ps;
10406             DWORD shader_code[] = {
10407                 0xffff0101,                                 /* ps_1_1           */
10408                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10409                 0x0000ffff                                  /* end              */
10410             };
10411             memset(&caps, 0, sizeof(caps));
10412             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10413             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10414             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10415                 break;
10416             }
10417
10418             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10419             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10420             IDirect3DDevice9_SetPixelShader(device, ps);
10421             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10422             IDirect3DPixelShader9_Release(ps);
10423         }
10424
10425         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10426             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10427             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10428
10429             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10430             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10431             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10432             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10433             hr = IDirect3DDevice9_BeginScene(device);
10434             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10435             if(SUCCEEDED(hr)) {
10436                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10437                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10438                 hr = IDirect3DDevice9_EndScene(device);
10439                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10440             }
10441             color = getPixelColor(device, 320, 240);
10442             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10443             color, testdata[i].color_less, testdata[i].func);
10444             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10445             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10446
10447             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10448             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10449             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10450             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10451             hr = IDirect3DDevice9_BeginScene(device);
10452             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10453             if(SUCCEEDED(hr)) {
10454                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10455                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10456                 hr = IDirect3DDevice9_EndScene(device);
10457                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10458             }
10459             color = getPixelColor(device, 320, 240);
10460             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10461             color, testdata[i].color_equal, testdata[i].func);
10462             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10463             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10464
10465             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10466             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10467             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10468             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10469             hr = IDirect3DDevice9_BeginScene(device);
10470             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10471             if(SUCCEEDED(hr)) {
10472                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10473                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10474                 hr = IDirect3DDevice9_EndScene(device);
10475                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10476             }
10477             color = getPixelColor(device, 320, 240);
10478             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10479             color, testdata[i].color_greater, testdata[i].func);
10480             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10481             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10482         }
10483     }
10484
10485     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10486     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10487     IDirect3DDevice9_SetPixelShader(device, NULL);
10488     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10489 }
10490
10491 static void sincos_test(IDirect3DDevice9 *device) {
10492     const DWORD sin_shader_code[] = {
10493         0xfffe0200,                                                                 /* vs_2_0                       */
10494         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10495         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10496         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10497         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10498         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10499         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10500         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10501         0x0000ffff                                                                  /* end                          */
10502     };
10503     const DWORD cos_shader_code[] = {
10504         0xfffe0200,                                                                 /* vs_2_0                       */
10505         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10506         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10507         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10508         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10509         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10510         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10511         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10512         0x0000ffff                                                                  /* end                          */
10513     };
10514     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10515     HRESULT hr;
10516     struct {
10517         float x, y, z;
10518     } data[1280];
10519     unsigned int i;
10520     float sincosc1[4] = {D3DSINCOSCONST1};
10521     float sincosc2[4] = {D3DSINCOSCONST2};
10522
10523     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10524     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10525
10526     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10527     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10528     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10529     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10530     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10531     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10532     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10533     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10534     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10535     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10536
10537     /* Generate a point from -1 to 1 every 0.5 pixels */
10538     for(i = 0; i < 1280; i++) {
10539         data[i].x = (-640.0 + i) / 640.0;
10540         data[i].y = 0.0;
10541         data[i].z = 0.1;
10542     }
10543
10544     hr = IDirect3DDevice9_BeginScene(device);
10545     if(SUCCEEDED(hr)) {
10546         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10547         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10548         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10549         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10550
10551         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10552         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10553         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10554         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10555
10556         hr = IDirect3DDevice9_EndScene(device);
10557         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10558     }
10559     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10560     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10561     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10562
10563     IDirect3DDevice9_SetVertexShader(device, NULL);
10564     IDirect3DVertexShader9_Release(sin_shader);
10565     IDirect3DVertexShader9_Release(cos_shader);
10566 }
10567
10568 static void loop_index_test(IDirect3DDevice9 *device) {
10569     const DWORD shader_code[] = {
10570         0xfffe0200,                                                 /* vs_2_0                   */
10571         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10572         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10573         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10574         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10575         0x0000001d,                                                 /* endloop                  */
10576         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10577         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10578         0x0000ffff                                                  /* END                      */
10579     };
10580     IDirect3DVertexShader9 *shader;
10581     HRESULT hr;
10582     DWORD color;
10583     const float quad[] = {
10584         -1.0,   -1.0,   0.1,
10585          1.0,   -1.0,   0.1,
10586         -1.0,    1.0,   0.1,
10587          1.0,    1.0,   0.1
10588     };
10589     const float zero[4] = {0, 0, 0, 0};
10590     const float one[4] = {1, 1, 1, 1};
10591     int i0[4] = {2, 10, -3, 0};
10592     float values[4];
10593
10594     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10595     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10596     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10597     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10598     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10599     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10600     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10601     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10602
10603     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10604     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10605     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10606     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10607     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10608     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10609     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10610     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10611     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10612     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10613     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10614     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10615     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10616     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10617     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10618     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10619     values[0] = 1.0;
10620     values[1] = 1.0;
10621     values[2] = 0.0;
10622     values[3] = 0.0;
10623     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10624     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10625     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10626     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10627     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10628     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10629     values[0] = -1.0;
10630     values[1] = 0.0;
10631     values[2] = 0.0;
10632     values[3] = 0.0;
10633     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10634     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10635     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10637     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10638     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10639     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10640     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10641     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10642     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10643
10644     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10645     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10646
10647     hr = IDirect3DDevice9_BeginScene(device);
10648     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10649     if(SUCCEEDED(hr))
10650     {
10651         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10652         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10653         hr = IDirect3DDevice9_EndScene(device);
10654         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10655     }
10656     color = getPixelColor(device, 320, 240);
10657     ok(color_match(color, 0x0000ff00, 1),
10658        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10659     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10660     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10661
10662     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10663     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10664     IDirect3DVertexShader9_Release(shader);
10665 }
10666
10667 static void sgn_test(IDirect3DDevice9 *device) {
10668     const DWORD shader_code[] = {
10669         0xfffe0200,                                                             /* vs_2_0                       */
10670         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10671         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10672         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10673         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10674         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10675         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10676         0x0000ffff                                                              /* end                          */
10677     };
10678     IDirect3DVertexShader9 *shader;
10679     HRESULT hr;
10680     DWORD color;
10681     const float quad[] = {
10682         -1.0,   -1.0,   0.1,
10683          1.0,   -1.0,   0.1,
10684         -1.0,    1.0,   0.1,
10685          1.0,    1.0,   0.1
10686     };
10687
10688     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10689     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10690     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10691     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10692     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10693     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10694     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10695     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10696
10697     hr = IDirect3DDevice9_BeginScene(device);
10698     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10699     if(SUCCEEDED(hr))
10700     {
10701         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10702         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10703         hr = IDirect3DDevice9_EndScene(device);
10704         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10705     }
10706     color = getPixelColor(device, 320, 240);
10707     ok(color_match(color, 0x008000ff, 1),
10708        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10709     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10710     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10711
10712     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10713     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10714     IDirect3DVertexShader9_Release(shader);
10715 }
10716
10717 static void viewport_test(IDirect3DDevice9 *device) {
10718     HRESULT hr;
10719     DWORD color;
10720     D3DVIEWPORT9 vp, old_vp;
10721     const float quad[] =
10722     {
10723         -0.5,   -0.5,   0.1,
10724          0.5,   -0.5,   0.1,
10725         -0.5,    0.5,   0.1,
10726          0.5,    0.5,   0.1
10727     };
10728
10729     memset(&old_vp, 0, sizeof(old_vp));
10730     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10731     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10732
10733     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10734     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10735
10736     /* Test a viewport with Width and Height bigger than the surface dimensions
10737      *
10738      * TODO: Test Width < surface.width, but X + Width > surface.width
10739      * TODO: Test Width < surface.width, what happens with the height?
10740      */
10741     memset(&vp, 0, sizeof(vp));
10742     vp.X = 0;
10743     vp.Y = 0;
10744     vp.Width = 10000;
10745     vp.Height = 10000;
10746     vp.MinZ = 0.0;
10747     vp.MaxZ = 0.0;
10748     hr = IDirect3DDevice9_SetViewport(device, &vp);
10749     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10750
10751     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10752     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10753     hr = IDirect3DDevice9_BeginScene(device);
10754     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10755     if(SUCCEEDED(hr))
10756     {
10757         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10758         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10759         hr = IDirect3DDevice9_EndScene(device);
10760         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10761     }
10762
10763     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10764     color = getPixelColor(device, 158, 118);
10765     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10766     color = getPixelColor(device, 162, 118);
10767     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10768     color = getPixelColor(device, 158, 122);
10769     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10770     color = getPixelColor(device, 162, 122);
10771     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10772
10773     color = getPixelColor(device, 478, 358);
10774     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10775     color = getPixelColor(device, 482, 358);
10776     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10777     color = getPixelColor(device, 478, 362);
10778     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10779     color = getPixelColor(device, 482, 362);
10780     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10781
10782     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10783     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10784
10785     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10786     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10787 }
10788
10789 /* This test tests depth clamping / clipping behaviour:
10790  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10791  *   minimum/maximum z value.
10792  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10793  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10794  *   - Pretransformed vertices behave the same as regular vertices.
10795  */
10796 static void depth_clamp_test(IDirect3DDevice9 *device)
10797 {
10798     const struct tvertex quad1[] =
10799     {
10800         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10801         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10802         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10803         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10804     };
10805     const struct tvertex quad2[] =
10806     {
10807         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10808         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10809         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10810         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10811     };
10812     const struct vertex quad3[] =
10813     {
10814         {-0.65, 0.55,  5.0f,      0xffffffff},
10815         {-0.35, 0.55,  5.0f,      0xffffffff},
10816         {-0.65, 0.15,  5.0f,      0xffffffff},
10817         {-0.35, 0.15,  5.0f,      0xffffffff},
10818     };
10819     const struct vertex quad4[] =
10820     {
10821         {-0.87, 0.83, 10.0f,      0xffffffff},
10822         {-0.65, 0.83, 10.0f,      0xffffffff},
10823         {-0.87, 0.55, 10.0f,      0xffffffff},
10824         {-0.65, 0.55, 10.0f,      0xffffffff},
10825     };
10826     const struct vertex quad5[] =
10827     {
10828         { -0.5,  0.5, 10.0f,      0xff14f914},
10829         {  0.5,  0.5, 10.0f,      0xff14f914},
10830         { -0.5, -0.5, 10.0f,      0xff14f914},
10831         {  0.5, -0.5, 10.0f,      0xff14f914},
10832     };
10833     const struct tvertex quad6[] =
10834     {
10835         {    0,  120, 10.0f, 1.0, 0xfff91414},
10836         {  640,  120, 10.0f, 1.0, 0xfff91414},
10837         {    0,  180, 10.0f, 1.0, 0xfff91414},
10838         {  640,  180, 10.0f, 1.0, 0xfff91414},
10839     };
10840
10841     D3DVIEWPORT9 vp;
10842     D3DCOLOR color;
10843     HRESULT hr;
10844
10845     vp.X = 0;
10846     vp.Y = 0;
10847     vp.Width = 640;
10848     vp.Height = 480;
10849     vp.MinZ = 0.0;
10850     vp.MaxZ = 7.5;
10851
10852     hr = IDirect3DDevice9_SetViewport(device, &vp);
10853     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10854
10855     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10856     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10857
10858     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10859     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10860     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10861     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10863     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10864     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10865     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10866
10867     hr = IDirect3DDevice9_BeginScene(device);
10868     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10869
10870     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10871     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10872
10873     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10874     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10875     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10876     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10877
10878     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10879     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10880
10881     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10882     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10883     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10884     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10885
10886     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10887     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10888
10889     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10890     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10891
10892     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10893     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10894
10895     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10896     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10897
10898     hr = IDirect3DDevice9_EndScene(device);
10899     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10900
10901     color = getPixelColor(device, 75, 75);
10902     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10903     color = getPixelColor(device, 150, 150);
10904     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10905     color = getPixelColor(device, 320, 240);
10906     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10907     color = getPixelColor(device, 320, 330);
10908     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10909     color = getPixelColor(device, 320, 330);
10910     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10911
10912     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10913     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10914
10915     vp.MinZ = 0.0;
10916     vp.MaxZ = 1.0;
10917     hr = IDirect3DDevice9_SetViewport(device, &vp);
10918     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10919 }
10920
10921 static void depth_buffer_test(IDirect3DDevice9 *device)
10922 {
10923     static const struct vertex quad1[] =
10924     {
10925         { -1.0,  1.0, 0.33f, 0xff00ff00},
10926         {  1.0,  1.0, 0.33f, 0xff00ff00},
10927         { -1.0, -1.0, 0.33f, 0xff00ff00},
10928         {  1.0, -1.0, 0.33f, 0xff00ff00},
10929     };
10930     static const struct vertex quad2[] =
10931     {
10932         { -1.0,  1.0, 0.50f, 0xffff00ff},
10933         {  1.0,  1.0, 0.50f, 0xffff00ff},
10934         { -1.0, -1.0, 0.50f, 0xffff00ff},
10935         {  1.0, -1.0, 0.50f, 0xffff00ff},
10936     };
10937     static const struct vertex quad3[] =
10938     {
10939         { -1.0,  1.0, 0.66f, 0xffff0000},
10940         {  1.0,  1.0, 0.66f, 0xffff0000},
10941         { -1.0, -1.0, 0.66f, 0xffff0000},
10942         {  1.0, -1.0, 0.66f, 0xffff0000},
10943     };
10944     static const DWORD expected_colors[4][4] =
10945     {
10946         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10947         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10948         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10949         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10950     };
10951
10952     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10953     unsigned int i, j;
10954     D3DVIEWPORT9 vp;
10955     D3DCOLOR color;
10956     HRESULT hr;
10957
10958     vp.X = 0;
10959     vp.Y = 0;
10960     vp.Width = 640;
10961     vp.Height = 480;
10962     vp.MinZ = 0.0;
10963     vp.MaxZ = 1.0;
10964
10965     hr = IDirect3DDevice9_SetViewport(device, &vp);
10966     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10967
10968     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10969     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10970     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10971     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10972     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10973     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10974     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10975     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10976     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10977     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10978
10979     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10980     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10981     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10982             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10983     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10984     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10985             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10986     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10987     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10988             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10989     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10990
10991     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10992     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10993     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10994     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10995
10996     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10997     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10998     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10999     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11000
11001     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11002     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11003     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11004     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11005
11006     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11007     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11008     hr = IDirect3DDevice9_BeginScene(device);
11009     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11010     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11011     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11012     hr = IDirect3DDevice9_EndScene(device);
11013     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11014
11015     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11016     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11017     IDirect3DSurface9_Release(backbuffer);
11018     IDirect3DSurface9_Release(rt3);
11019     IDirect3DSurface9_Release(rt2);
11020     IDirect3DSurface9_Release(rt1);
11021
11022     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11023     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11024
11025     hr = IDirect3DDevice9_BeginScene(device);
11026     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11027     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11028     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11029     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11030     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11031     hr = IDirect3DDevice9_EndScene(device);
11032     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11033
11034     for (i = 0; i < 4; ++i)
11035     {
11036         for (j = 0; j < 4; ++j)
11037         {
11038             unsigned int x = 80 * ((2 * j) + 1);
11039             unsigned int y = 60 * ((2 * i) + 1);
11040             color = getPixelColor(device, x, y);
11041             ok(color_match(color, expected_colors[i][j], 0),
11042                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11043         }
11044     }
11045
11046     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11047     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11048 }
11049
11050 START_TEST(visual)
11051 {
11052     IDirect3DDevice9 *device_ptr;
11053     D3DCAPS9 caps;
11054     HRESULT hr;
11055     DWORD color;
11056
11057     d3d9_handle = LoadLibraryA("d3d9.dll");
11058     if (!d3d9_handle)
11059     {
11060         skip("Could not load d3d9.dll\n");
11061         return;
11062     }
11063
11064     device_ptr = init_d3d9();
11065     if (!device_ptr)
11066     {
11067         skip("Creating the device failed\n");
11068         return;
11069     }
11070
11071     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11072
11073     /* Check for the reliability of the returned data */
11074     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11075     if(FAILED(hr))
11076     {
11077         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11078         goto cleanup;
11079     }
11080
11081     color = getPixelColor(device_ptr, 1, 1);
11082     if(color !=0x00ff0000)
11083     {
11084         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11085         goto cleanup;
11086     }
11087     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11088
11089     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11090     if(FAILED(hr))
11091     {
11092         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11093         goto cleanup;
11094     }
11095
11096     color = getPixelColor(device_ptr, 639, 479);
11097     if(color != 0x0000ddee)
11098     {
11099         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11100         goto cleanup;
11101     }
11102     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11103
11104     /* Now execute the real tests */
11105     depth_clamp_test(device_ptr);
11106     stretchrect_test(device_ptr);
11107     lighting_test(device_ptr);
11108     clear_test(device_ptr);
11109     color_fill_test(device_ptr);
11110     fog_test(device_ptr);
11111     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11112     {
11113         test_cube_wrap(device_ptr);
11114     } else {
11115         skip("No cube texture support\n");
11116     }
11117     z_range_test(device_ptr);
11118     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11119     {
11120         maxmip_test(device_ptr);
11121     }
11122     else
11123     {
11124         skip("No mipmap support\n");
11125     }
11126     offscreen_test(device_ptr);
11127     alpha_test(device_ptr);
11128     shademode_test(device_ptr);
11129     srgbtexture_test(device_ptr);
11130     release_buffer_test(device_ptr);
11131     float_texture_test(device_ptr);
11132     g16r16_texture_test(device_ptr);
11133     pixelshader_blending_test(device_ptr);
11134     texture_transform_flags_test(device_ptr);
11135     autogen_mipmap_test(device_ptr);
11136     fixed_function_decl_test(device_ptr);
11137     conditional_np2_repeat_test(device_ptr);
11138     fixed_function_bumpmap_test(device_ptr);
11139     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11140         stencil_cull_test(device_ptr);
11141     } else {
11142         skip("No two sided stencil support\n");
11143     }
11144     pointsize_test(device_ptr);
11145     tssargtemp_test(device_ptr);
11146     np2_stretch_rect_test(device_ptr);
11147     yuv_color_test(device_ptr);
11148     zwriteenable_test(device_ptr);
11149     alphatest_test(device_ptr);
11150     viewport_test(device_ptr);
11151
11152     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11153     {
11154         test_constant_clamp_vs(device_ptr);
11155         test_compare_instructions(device_ptr);
11156     }
11157     else skip("No vs_1_1 support\n");
11158
11159     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11160     {
11161         test_mova(device_ptr);
11162         loop_index_test(device_ptr);
11163         sincos_test(device_ptr);
11164         sgn_test(device_ptr);
11165         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11166             test_vshader_input(device_ptr);
11167             test_vshader_float16(device_ptr);
11168             stream_test(device_ptr);
11169         } else {
11170             skip("No vs_3_0 support\n");
11171         }
11172     }
11173     else skip("No vs_2_0 support\n");
11174
11175     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11176     {
11177         fog_with_shader_test(device_ptr);
11178         fog_srgbwrite_test(device_ptr);
11179     }
11180     else skip("No vs_1_1 and ps_1_1 support\n");
11181
11182     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11183     {
11184         texbem_test(device_ptr);
11185         texdepth_test(device_ptr);
11186         texkill_test(device_ptr);
11187         x8l8v8u8_test(device_ptr);
11188         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11189             constant_clamp_ps_test(device_ptr);
11190             cnd_test(device_ptr);
11191             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11192                 dp2add_ps_test(device_ptr);
11193                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
11194                     nested_loop_test(device_ptr);
11195                     fixed_function_varying_test(device_ptr);
11196                     vFace_register_test(device_ptr);
11197                     vpos_register_test(device_ptr);
11198                     multiple_rendertargets_test(device_ptr);
11199                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11200                         vshader_version_varying_test(device_ptr);
11201                         pshader_version_varying_test(device_ptr);
11202                     } else {
11203                         skip("No vs_3_0 support\n");
11204                     }
11205                 } else {
11206                     skip("No ps_3_0 support\n");
11207                 }
11208             } else {
11209                 skip("No ps_2_0 support\n");
11210             }
11211         }
11212     }
11213     else skip("No ps_1_1 support\n");
11214
11215     texop_test(device_ptr);
11216     texop_range_test(device_ptr);
11217     alphareplicate_test(device_ptr);
11218     dp3_alpha_test(device_ptr);
11219     depth_buffer_test(device_ptr);
11220
11221 cleanup:
11222     if(device_ptr) {
11223         D3DPRESENT_PARAMETERS present_parameters;
11224         IDirect3DSwapChain9 *swapchain;
11225         ULONG ref;
11226
11227         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11228         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11229         IDirect3DSwapChain9_Release(swapchain);
11230         ref = IDirect3DDevice9_Release(device_ptr);
11231         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11232         DestroyWindow(present_parameters.hDeviceWindow);
11233     }
11234 }