msi/tests: Skip some source tests if a required product key cannot be created.
[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. The way this test works is
1147  * that we sample in one of the corners of the cubemap with filtering enabled,
1148  * and check the interpolated color. There are essentially two reasonable
1149  * things an implementation can do: Either pick one of the faces and
1150  * interpolate the edge texel with itself (i.e., clamp within the face), or
1151  * interpolate between the edge texels of the three involved faces. It should
1152  * never involve the border color or the other side (texcoord wrapping) of a
1153  * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1155 {
1156     static const float quad[][6] = {
1157         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161     };
1162
1163     static const D3DVERTEXELEMENT9 decl_elements[] = {
1164         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166         D3DDECL_END()
1167     };
1168
1169     static const struct {
1170         D3DTEXTUREADDRESS mode;
1171         const char *name;
1172     } address_modes[] = {
1173         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1178     };
1179
1180     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181     IDirect3DCubeTexture9 *texture = NULL;
1182     IDirect3DSurface9 *surface = NULL;
1183     IDirect3DSurface9 *face_surface;
1184     D3DLOCKED_RECT locked_rect;
1185     HRESULT hr;
1186     UINT x;
1187     INT y, face;
1188
1189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1193
1194     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1197
1198     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199             D3DPOOL_DEFAULT, &texture, NULL);
1200     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1201
1202     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1204
1205     for (y = 0; y < 128; ++y)
1206     {
1207         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208         for (x = 0; x < 64; ++x)
1209         {
1210             *ptr++ = 0xff0000ff;
1211         }
1212         for (x = 64; x < 128; ++x)
1213         {
1214             *ptr++ = 0xffff0000;
1215         }
1216     }
1217
1218     hr = IDirect3DSurface9_UnlockRect(surface);
1219     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1220
1221     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1223
1224     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1226
1227     IDirect3DSurface9_Release(face_surface);
1228
1229     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1231
1232     for (y = 0; y < 128; ++y)
1233     {
1234         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235         for (x = 0; x < 64; ++x)
1236         {
1237             *ptr++ = 0xffff0000;
1238         }
1239         for (x = 64; x < 128; ++x)
1240         {
1241             *ptr++ = 0xff0000ff;
1242         }
1243     }
1244
1245     hr = IDirect3DSurface9_UnlockRect(surface);
1246     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1247
1248     /* Create cube faces */
1249     for (face = 1; face < 6; ++face)
1250     {
1251         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1253
1254         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1256
1257         IDirect3DSurface9_Release(face_surface);
1258     }
1259
1260     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1262
1263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1269
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1274     {
1275         DWORD color;
1276
1277         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1281
1282         hr = IDirect3DDevice9_BeginScene(device);
1283         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1284
1285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1287
1288         hr = IDirect3DDevice9_EndScene(device);
1289         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1290
1291         color = getPixelColor(device, 320, 240);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294                 color, address_modes[x].name);
1295
1296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1298
1299         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1301     }
1302
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1305
1306     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307     IDirect3DCubeTexture9_Release(texture);
1308     IDirect3DSurface9_Release(surface);
1309 }
1310
1311 static void offscreen_test(IDirect3DDevice9 *device)
1312 {
1313     HRESULT hr;
1314     IDirect3DTexture9 *offscreenTexture = NULL;
1315     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316     DWORD color;
1317
1318     static const float quad[][5] = {
1319         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1321         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1323     };
1324
1325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1327
1328     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330     if(!offscreenTexture) {
1331         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334         if(!offscreenTexture) {
1335             skip("Cannot create an offscreen render target\n");
1336             goto out;
1337         }
1338     }
1339
1340     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342     if(!backbuffer) {
1343         goto out;
1344     }
1345
1346     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348     if(!offscreen) {
1349         goto out;
1350     }
1351
1352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1354
1355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1365
1366     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1371
1372         /* Draw without textures - Should result in a white quad */
1373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1375
1376         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1380
1381         /* This time with the texture */
1382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1384
1385         IDirect3DDevice9_EndScene(device);
1386     }
1387
1388     /* Center quad - should be white */
1389     color = getPixelColor(device, 320, 240);
1390     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391     /* Some quad in the cleared part of the texture */
1392     color = getPixelColor(device, 170, 240);
1393     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394     /* Part of the originally cleared back buffer */
1395     color = getPixelColor(device, 10, 10);
1396     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397     if(0) {
1398         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400          * the offscreen rendering mode this test would succeed or fail
1401          */
1402         color = getPixelColor(device, 10, 470);
1403         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1404     }
1405
1406     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1407
1408 out:
1409     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1411
1412     /* restore things */
1413     if(backbuffer) {
1414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416         IDirect3DSurface9_Release(backbuffer);
1417     }
1418     if(offscreenTexture) {
1419         IDirect3DTexture9_Release(offscreenTexture);
1420     }
1421     if(offscreen) {
1422         IDirect3DSurface9_Release(offscreen);
1423     }
1424 }
1425
1426 /* This test tests fog in combination with shaders.
1427  * What's tested: linear fog (vertex and table) with pixel shader
1428  *                linear table fog with non foggy vertex shader
1429  *                vertex fog with foggy vertex shader, non-linear
1430  *                fog with shader, non-linear fog with foggy shader,
1431  *                linear table fog with foggy shader
1432  */
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1434 {
1435     HRESULT hr;
1436     DWORD color;
1437     union {
1438         float f;
1439         DWORD i;
1440     } start, end;
1441     unsigned int i, j;
1442
1443     /* basic vertex shader without fog computation ("non foggy") */
1444     static const DWORD vertex_shader_code1[] = {
1445         0xfffe0101,                                                             /* vs_1_1                       */
1446         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1447         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1448         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1449         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1450         0x0000ffff
1451     };
1452     /* basic vertex shader with reversed fog computation ("foggy") */
1453     static const DWORD vertex_shader_code2[] = {
1454         0xfffe0101,                                                             /* vs_1_1                        */
1455         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1456         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1457         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1459         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1460         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1461         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1462         0x0000ffff
1463     };
1464     /* basic pixel shader */
1465     static const DWORD pixel_shader_code[] = {
1466         0xffff0101,                                                             /* ps_1_1     */
1467         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1468         0x0000ffff
1469     };
1470
1471     static struct vertex quad[] = {
1472         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1473         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1474         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1476     };
1477
1478     static const D3DVERTEXELEMENT9 decl_elements[] = {
1479         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1481         D3DDECL_END()
1482     };
1483
1484     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1486     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1487
1488     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489     static const struct test_data_t {
1490         int vshader;
1491         int pshader;
1492         D3DFOGMODE vfog;
1493         D3DFOGMODE tfog;
1494         unsigned int color[11];
1495     } test_data[] = {
1496         /* only pixel shader: */
1497         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512
1513         /* vertex shader */
1514         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523
1524         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader and pixel shader */
1532         /* The next 4 tests would read the fog coord output, but it isn't available.
1533          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535          * These tests should be disabled if some other hardware behaves differently
1536          */
1537         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1549
1550         /* These use the Z coordinate with linear table fog */
1551         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1563
1564         /* Non-linear table fog without fog coord */
1565         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1571
1572 #if 0  /* FIXME: these fail on GeForce 8500 */
1573         /* foggy vertex shader */
1574         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1587
1588         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589          * all using the fixed fog-coord linear fog
1590          */
1591         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1603
1604         /* These use table fog. Here the shader-provided fog coordinate is
1605          * ignored and the z coordinate used instead
1606          */
1607         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1616     };
1617
1618     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619     start.f=0.1f;
1620     end.f=0.9f;
1621
1622     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1630
1631     /* Setup initial states: No lighting, fog on, fog color */
1632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1640
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1645
1646     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1651
1652     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1653     {
1654         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1662
1663         for(j=0; j < 11; j++)
1664         {
1665             /* Don't use the whole zrange to prevent rounding errors */
1666             quad[0].z = 0.001f + (float)j / 10.02f;
1667             quad[1].z = 0.001f + (float)j / 10.02f;
1668             quad[2].z = 0.001f + (float)j / 10.02f;
1669             quad[3].z = 0.001f + (float)j / 10.02f;
1670
1671             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1673
1674             hr = IDirect3DDevice9_BeginScene(device);
1675             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1676
1677             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679
1680             hr = IDirect3DDevice9_EndScene(device);
1681             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1682
1683             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684             color = getPixelColor(device, 128, 240);
1685             ok(color_match(color, test_data[i].color[j], 13),
1686                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1688
1689             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1690         }
1691     }
1692
1693     /* reset states */
1694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1702
1703     IDirect3DVertexShader9_Release(vertex_shader[1]);
1704     IDirect3DVertexShader9_Release(vertex_shader[2]);
1705     IDirect3DPixelShader9_Release(pixel_shader[1]);
1706     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1707 }
1708
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710     unsigned int i, x, y;
1711     HRESULT hr;
1712     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713     D3DLOCKED_RECT locked_rect;
1714
1715     /* Generate the textures */
1716     for(i=0; i<2; i++)
1717     {
1718         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719                                             D3DPOOL_MANAGED, &texture[i], NULL);
1720         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1721
1722         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724         for (y = 0; y < 128; ++y)
1725         {
1726             if(i)
1727             { /* Set up black texture with 2x2 texel white spot in the middle */
1728                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729                 for (x = 0; x < 128; ++x)
1730                 {
1731                     if(y>62 && y<66 && x>62 && x<66)
1732                         *ptr++ = 0xffffffff;
1733                     else
1734                         *ptr++ = 0xff000000;
1735                 }
1736             }
1737             else
1738             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739                * (if multiplied with bumpenvmat)
1740               */
1741                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(abs(x-64)>abs(y-64))
1745                     {
1746                         if(x < 64)
1747                             *ptr++ = 0xc000;
1748                         else
1749                             *ptr++ = 0x4000;
1750                     }
1751                     else
1752                     {
1753                         if(y < 64)
1754                             *ptr++ = 0x0040;
1755                         else
1756                             *ptr++ = 0x00c0;
1757                     }
1758                 }
1759             }
1760         }
1761         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1763
1764         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1766
1767         /* Disable texture filtering */
1768         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1772
1773         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1777     }
1778 }
1779
1780 /* test the behavior of the texbem instruction
1781  * with normal 2D and projective 2D textures
1782  */
1783 static void texbem_test(IDirect3DDevice9 *device)
1784 {
1785     HRESULT hr;
1786     DWORD color;
1787     int i;
1788
1789     static const DWORD pixel_shader_code[] = {
1790         0xffff0101,                         /* ps_1_1*/
1791         0x00000042, 0xb00f0000,             /* tex t0*/
1792         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794         0x0000ffff
1795     };
1796     static const DWORD double_texbem_code[] =  {
1797         0xffff0103,                                         /* ps_1_3           */
1798         0x00000042, 0xb00f0000,                             /* tex t0           */
1799         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1800         0x00000042, 0xb00f0002,                             /* tex t2           */
1801         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1802         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1803         0x0000ffff                                          /* end              */
1804     };
1805
1806
1807     static const float quad[][7] = {
1808         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1812     };
1813     static const float quad_proj[][9] = {
1814         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1815         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1816         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1818     };
1819
1820     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824         D3DDECL_END()
1825     },{
1826         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829         D3DDECL_END()
1830     } };
1831
1832     /* use asymmetric matrix to test loading */
1833     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1834
1835     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836     IDirect3DPixelShader9       *pixel_shader       = NULL;
1837     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1838     D3DLOCKED_RECT locked_rect;
1839
1840     generate_bumpmap_textures(device);
1841
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1847
1848     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1850
1851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1853
1854     for(i=0; i<2; i++)
1855     {
1856         if(i)
1857         {
1858             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1860         }
1861
1862         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1866
1867         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1871
1872         hr = IDirect3DDevice9_BeginScene(device);
1873         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874
1875         if(!i)
1876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877         else
1878             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1880
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883
1884         color = getPixelColor(device, 320-32, 240);
1885         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886         color = getPixelColor(device, 320+32, 240);
1887         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888         color = getPixelColor(device, 320, 240-32);
1889         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890         color = getPixelColor(device, 320, 240+32);
1891         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1895
1896         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898         IDirect3DPixelShader9_Release(pixel_shader);
1899
1900         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1903     }
1904
1905     /* clean up */
1906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1911
1912     for(i=0; i<2; i++)
1913     {
1914         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919         IDirect3DTexture9_Release(texture);
1920     }
1921
1922     /* Test double texbem */
1923     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1931
1932     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1936
1937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1939
1940     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1946
1947     {
1948         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex  0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952         static const DWORD pixel_data[] = {
1953             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961         };
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1965
1966         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968         for(i = 0; i < 8; i++) {
1969             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1970         }
1971         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1973     }
1974
1975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1987
1988     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1989     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1998
1999     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2000     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2001     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009
2010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2026
2027     hr = IDirect3DDevice9_BeginScene(device);
2028     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029     if(SUCCEEDED(hr)) {
2030         static const float double_quad[] = {
2031             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2032              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035         };
2036
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039         hr = IDirect3DDevice9_EndScene(device);
2040         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2041     }
2042     color = getPixelColor(device, 320, 240);
2043     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2044
2045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2055
2056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058
2059     IDirect3DPixelShader9_Release(pixel_shader);
2060     IDirect3DTexture9_Release(texture);
2061     IDirect3DTexture9_Release(texture1);
2062     IDirect3DTexture9_Release(texture2);
2063 }
2064
2065 static void z_range_test(IDirect3DDevice9 *device)
2066 {
2067     const struct vertex quad[] =
2068     {
2069         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2070         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2071         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2072         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2073     };
2074     const struct vertex quad2[] =
2075     {
2076         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2077         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2078         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2079         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2080     };
2081
2082     const struct tvertex quad3[] =
2083     {
2084         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2085         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2086         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2087         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2088     };
2089     const struct tvertex quad4[] =
2090     {
2091         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2092         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2093         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2094         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2095     };
2096     HRESULT hr;
2097     DWORD color;
2098     IDirect3DVertexShader9 *shader;
2099     IDirect3DVertexDeclaration9 *decl;
2100     D3DCAPS9 caps;
2101     const DWORD shader_code[] = {
2102         0xfffe0101,                                     /* vs_1_1           */
2103         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2104         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2105         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2106         0x0000ffff                                      /* end              */
2107     };
2108     static const D3DVERTEXELEMENT9 decl_elements[] = {
2109         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110         D3DDECL_END()
2111     };
2112     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113      * then call Present. Then clear the color buffer to make sure it has some defined content
2114      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115      * by the depth value.
2116      */
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2123
2124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2134
2135     hr = IDirect3DDevice9_BeginScene(device);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137     if(hr == D3D_OK)
2138     {
2139         /* Test the untransformed vertex path */
2140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2146
2147         /* Test the transformed vertex path */
2148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2157
2158         hr = IDirect3DDevice9_EndScene(device);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2160     }
2161
2162     /* Do not test the exact corner pixels, but go pretty close to them */
2163
2164     /* Clipped because z > 1.0 */
2165     color = getPixelColor(device, 28, 238);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167     color = getPixelColor(device, 28, 241);
2168     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2169
2170     /* Not clipped, > z buffer clear value(0.75) */
2171     color = getPixelColor(device, 31, 238);
2172     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173     color = getPixelColor(device, 31, 241);
2174     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175     color = getPixelColor(device, 100, 238);
2176     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177     color = getPixelColor(device, 100, 241);
2178     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2179
2180     /* Not clipped, < z buffer clear value */
2181     color = getPixelColor(device, 104, 238);
2182     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183     color = getPixelColor(device, 104, 241);
2184     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185     color = getPixelColor(device, 318, 238);
2186     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187     color = getPixelColor(device, 318, 241);
2188     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2189
2190     /* Clipped because z < 0.0 */
2191     color = getPixelColor(device, 321, 238);
2192     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193     color = getPixelColor(device, 321, 241);
2194     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2195
2196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2198
2199     /* Test the shader path */
2200     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202         skip("Vertex shaders not supported\n");
2203         goto out;
2204     }
2205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2209
2210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2211
2212     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214     IDirect3DDevice9_SetVertexShader(device, shader);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2216
2217     hr = IDirect3DDevice9_BeginScene(device);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219     if(hr == D3D_OK)
2220     {
2221         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2231
2232         hr = IDirect3DDevice9_EndScene(device);
2233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2234     }
2235
2236     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238     IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2240
2241     IDirect3DVertexDeclaration9_Release(decl);
2242     IDirect3DVertexShader9_Release(shader);
2243
2244     /* Z < 1.0 */
2245     color = getPixelColor(device, 28, 238);
2246     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2247
2248     /* 1.0 < z < 0.75 */
2249     color = getPixelColor(device, 31, 238);
2250     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251     color = getPixelColor(device, 100, 238);
2252     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2253
2254     /* 0.75 < z < 0.0 */
2255     color = getPixelColor(device, 104, 238);
2256     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257     color = getPixelColor(device, 318, 238);
2258     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2259
2260     /* 0.0 < z */
2261     color = getPixelColor(device, 321, 238);
2262     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2263
2264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2266
2267     out:
2268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2274 }
2275
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2277 {
2278     D3DSURFACE_DESC desc;
2279     D3DLOCKED_RECT l;
2280     HRESULT hr;
2281     unsigned int x, y;
2282     DWORD *mem;
2283
2284     memset(&desc, 0, sizeof(desc));
2285     memset(&l, 0, sizeof(l));
2286     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290     if(FAILED(hr)) return;
2291
2292     for(y = 0; y < desc.Height; y++)
2293     {
2294         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2296         {
2297             mem[x] = color;
2298         }
2299     }
2300     hr = IDirect3DSurface9_UnlockRect(surface);
2301     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2302 }
2303
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2306 {
2307     HRESULT hr;
2308     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315     IDirect3DSurface9 *orig_rt = NULL;
2316     IDirect3DSurface9 *backbuffer = NULL;
2317     DWORD color;
2318
2319     RECT src_rect64 = {0, 0, 64, 64};
2320     RECT src_rect64_flipy = {0, 64, 64, 0};
2321     RECT dst_rect64 = {0, 0, 64, 64};
2322     RECT dst_rect64_flipy = {0, 64, 64, 0};
2323
2324     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326     if(!orig_rt) {
2327         goto out;
2328     }
2329
2330     /* Create our temporary surfaces in system memory */
2331     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2335
2336     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2343
2344     /* Create render target surfaces */
2345     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2353
2354     /* Create render target textures */
2355     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363     if (tex_rt32) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_rt64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371     if (tex_rt_dest64) {
2372         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2374     }
2375     if (tex_rt_dest64) {
2376         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2378     }
2379
2380     /* Create regular textures in D3DPOOL_DEFAULT */
2381     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387     if (tex32) {
2388         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2390     }
2391     if (tex64) {
2392         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2394     }
2395     if (tex_dest64) {
2396         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398     }
2399
2400     /*********************************************************************
2401      * Tests for when the source parameter is an offscreen plain surface *
2402      *********************************************************************/
2403
2404     /* Fill the offscreen 64x64 surface with green */
2405     if (surf_offscreen64)
2406         fill_surface(surf_offscreen64, 0xff00ff00);
2407
2408     /* offscreenplain ==> offscreenplain, same size */
2409     if(surf_offscreen64 && surf_offscreen_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2416         }
2417
2418         /* Blit without scaling */
2419         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421
2422         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425
2426         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429     }
2430
2431     /* offscreenplain ==> rendertarget texture, same size */
2432     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         /* We can't lock rendertarget textures, so copy to our temp surface first */
2437         if (hr == D3D_OK) {
2438             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2440         }
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget surface, same size */
2461     if(surf_offscreen64 && surf_rt_dest64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         if (hr == D3D_OK) {
2466             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2468         }
2469
2470         /* Blit without scaling */
2471         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473
2474         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481     }
2482
2483     /* offscreenplain ==> texture, same size (should fail) */
2484     if(surf_offscreen64 && surf_tex_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2487     }
2488
2489     /* Fill the smaller offscreen surface with red */
2490     fill_surface(surf_offscreen32, 0xffff0000);
2491
2492     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493     if(surf_offscreen32 && surf_offscreen64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* offscreenplain ==> rendertarget texture, scaling */
2499     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* We can't lock rendertarget textures, so copy to our temp surface first */
2504         if (hr == D3D_OK) {
2505             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2507         }
2508
2509         if (hr == D3D_OK) {
2510             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512         }
2513     }
2514
2515     /* offscreenplain ==> rendertarget surface, scaling */
2516     if(surf_offscreen32 && surf_rt_dest64) {
2517         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519
2520         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2522     }
2523
2524     /* offscreenplain ==> texture, scaling (should fail) */
2525     if(surf_offscreen32 && surf_tex_dest64) {
2526         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2528     }
2529
2530     /************************************************************
2531      * Tests for when the source parameter is a regular texture *
2532      ************************************************************/
2533
2534     /* Fill the surface of the regular texture with blue */
2535     if (surf_tex64 && surf_temp64) {
2536         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537         fill_surface(surf_temp64, 0xff0000ff);
2538         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2540     }
2541
2542     /* texture ==> offscreenplain, same size */
2543     if(surf_tex64 && surf_offscreen64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /* texture ==> rendertarget texture, same size */
2549     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         /* We can't lock rendertarget textures, so copy to our temp surface first */
2554         if (hr == D3D_OK) {
2555             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2557         }
2558
2559         if (hr == D3D_OK) {
2560             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2562         }
2563
2564         /* Blit without scaling */
2565         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571
2572         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575     }
2576
2577     /* texture ==> rendertarget surface, same size */
2578     if(surf_tex64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2585         }
2586
2587         /* Blit without scaling */
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590
2591         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594
2595         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2598     }
2599
2600     /* texture ==> texture, same size (should fail) */
2601     if(surf_tex64 && surf_tex_dest64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604     }
2605
2606     /* Fill the surface of the smaller regular texture with red */
2607     if (surf_tex32 && surf_temp32) {
2608         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609         fill_surface(surf_temp32, 0xffff0000);
2610         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2612     }
2613
2614     /* texture ==> offscreenplain, scaling (should fail) */
2615     if(surf_tex32 && surf_offscreen64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2618     }
2619
2620     /* texture ==> rendertarget texture, scaling */
2621     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* We can't lock rendertarget textures, so copy to our temp surface first */
2626         if (hr == D3D_OK) {
2627             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2629         }
2630
2631         if (hr == D3D_OK) {
2632             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634         }
2635     }
2636
2637     /* texture ==> rendertarget surface, scaling */
2638     if(surf_tex32 && surf_rt_dest64) {
2639         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2644     }
2645
2646     /* texture ==> texture, scaling (should fail) */
2647     if(surf_tex32 && surf_tex_dest64) {
2648         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2650     }
2651
2652     /*****************************************************************
2653      * Tests for when the source parameter is a rendertarget texture *
2654      *****************************************************************/
2655
2656     /* Fill the surface of the rendertarget texture with white */
2657     if (surf_tex_rt64 && surf_temp64) {
2658         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659         fill_surface(surf_temp64, 0xffffffff);
2660         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2662     }
2663
2664     /* rendertarget texture ==> offscreenplain, same size */
2665     if(surf_tex_rt64 && surf_offscreen64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /* rendertarget texture ==> rendertarget texture, same size */
2671     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2674
2675         /* We can't lock rendertarget textures, so copy to our temp surface first */
2676         if (hr == D3D_OK) {
2677             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2679         }
2680
2681         if (hr == D3D_OK) {
2682             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2684         }
2685
2686         /* Blit without scaling */
2687         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689
2690         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693
2694         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697     }
2698
2699     /* rendertarget texture ==> rendertarget surface, same size */
2700     if(surf_tex_rt64 && surf_rt_dest64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         if (hr == D3D_OK) {
2705             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2707         }
2708
2709         /* Blit without scaling */
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712
2713         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2716
2717         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720     }
2721
2722     /* rendertarget texture ==> texture, same size (should fail) */
2723     if(surf_tex_rt64 && surf_tex_dest64) {
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2726     }
2727
2728     /* Fill the surface of the smaller rendertarget texture with red */
2729     if (surf_tex_rt32 && surf_temp32) {
2730         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731         fill_surface(surf_temp32, 0xffff0000);
2732         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2734     }
2735
2736     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737     if(surf_tex_rt32 && surf_offscreen64) {
2738         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2740     }
2741
2742     /* rendertarget texture ==> rendertarget texture, scaling */
2743     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* We can't lock rendertarget textures, so copy to our temp surface first */
2748         if (hr == D3D_OK) {
2749             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2751         }
2752
2753         if (hr == D3D_OK) {
2754             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2756         }
2757     }
2758
2759     /* rendertarget texture ==> rendertarget surface, scaling */
2760     if(surf_tex_rt32 && surf_rt_dest64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763
2764         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2766     }
2767
2768     /* rendertarget texture ==> texture, scaling (should fail) */
2769     if(surf_tex_rt32 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /*****************************************************************
2775      * Tests for when the source parameter is a rendertarget surface *
2776      *****************************************************************/
2777
2778     /* Fill the surface of the rendertarget surface with black */
2779     if (surf_rt64)
2780         fill_surface(surf_rt64, 0xff000000);
2781
2782     /* rendertarget texture ==> offscreenplain, same size */
2783     if(surf_rt64 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* rendertarget surface ==> rendertarget texture, same size */
2789     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         /* We can't lock rendertarget textures, so copy to our temp surface first */
2794         if (hr == D3D_OK) {
2795             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2797         }
2798
2799         if (hr == D3D_OK) {
2800             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2802         }
2803
2804         /* Blit without scaling */
2805         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2807
2808         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811
2812         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815     }
2816
2817     /* rendertarget surface ==> rendertarget surface, same size */
2818     if(surf_rt64 && surf_rt_dest64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         if (hr == D3D_OK) {
2823             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2825         }
2826
2827         /* Blit without scaling */
2828         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830
2831         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838     }
2839
2840     /* rendertarget surface ==> texture, same size (should fail) */
2841     if(surf_rt64 && surf_tex_dest64) {
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2844     }
2845
2846     /* Fill the surface of the smaller rendertarget texture with red */
2847     if (surf_rt32)
2848         fill_surface(surf_rt32, 0xffff0000);
2849
2850     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851     if(surf_rt32 && surf_offscreen64) {
2852         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2854     }
2855
2856     /* rendertarget surface ==> rendertarget texture, scaling */
2857     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* We can't lock rendertarget textures, so copy to our temp surface first */
2862         if (hr == D3D_OK) {
2863             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2865         }
2866
2867         if (hr == D3D_OK) {
2868             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2870         }
2871     }
2872
2873     /* rendertarget surface ==> rendertarget surface, scaling */
2874     if(surf_rt32 && surf_rt_dest64) {
2875         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2877
2878         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2880     }
2881
2882     /* rendertarget surface ==> texture, scaling (should fail) */
2883     if(surf_rt32 && surf_tex_dest64) {
2884         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2886     }
2887
2888     /* backbuffer ==> surface tests (no scaling) */
2889     if(backbuffer && surf_tex_rt_dest640_480)
2890     {
2891         RECT src_rect = {0, 0, 640, 480};
2892         RECT src_rect_flipy = {0, 480, 640, 0};
2893         RECT dst_rect = {0, 0, 640, 480};
2894         RECT dst_rect_flipy = {0, 480, 640, 0};
2895
2896         /* Blit with NULL rectangles */
2897         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2899
2900         /* Blit without scaling */
2901         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2903
2904         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907
2908         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911     }
2912
2913     /* TODO: Test format conversions */
2914
2915
2916 out:
2917     /* Clean up */
2918     if (backbuffer)
2919         IDirect3DSurface9_Release(backbuffer);
2920     if (surf_rt32)
2921         IDirect3DSurface9_Release(surf_rt32);
2922     if (surf_rt64)
2923         IDirect3DSurface9_Release(surf_rt64);
2924     if (surf_rt_dest64)
2925         IDirect3DSurface9_Release(surf_rt_dest64);
2926     if (surf_temp32)
2927         IDirect3DSurface9_Release(surf_temp32);
2928     if (surf_temp64)
2929         IDirect3DSurface9_Release(surf_temp64);
2930     if (surf_offscreen32)
2931         IDirect3DSurface9_Release(surf_offscreen32);
2932     if (surf_offscreen64)
2933         IDirect3DSurface9_Release(surf_offscreen64);
2934     if (surf_offscreen_dest64)
2935         IDirect3DSurface9_Release(surf_offscreen_dest64);
2936
2937     if (tex_rt32) {
2938         if (surf_tex_rt32)
2939             IDirect3DSurface9_Release(surf_tex_rt32);
2940         IDirect3DTexture9_Release(tex_rt32);
2941     }
2942     if (tex_rt64) {
2943         if (surf_tex_rt64)
2944             IDirect3DSurface9_Release(surf_tex_rt64);
2945         IDirect3DTexture9_Release(tex_rt64);
2946     }
2947     if (tex_rt_dest64) {
2948         if (surf_tex_rt_dest64)
2949             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950         IDirect3DTexture9_Release(tex_rt_dest64);
2951     }
2952     if (tex_rt_dest640_480) {
2953         if (surf_tex_rt_dest640_480)
2954             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955         IDirect3DTexture9_Release(tex_rt_dest640_480);
2956     }
2957     if (tex32) {
2958         if (surf_tex32)
2959             IDirect3DSurface9_Release(surf_tex32);
2960         IDirect3DTexture9_Release(tex32);
2961     }
2962     if (tex64) {
2963         if (surf_tex64)
2964             IDirect3DSurface9_Release(surf_tex64);
2965         IDirect3DTexture9_Release(tex64);
2966     }
2967     if (tex_dest64) {
2968         if (surf_tex_dest64)
2969             IDirect3DSurface9_Release(surf_tex_dest64);
2970         IDirect3DTexture9_Release(tex_dest64);
2971     }
2972
2973     if (orig_rt) {
2974         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976         IDirect3DSurface9_Release(orig_rt);
2977     }
2978 }
2979
2980 static void maxmip_test(IDirect3DDevice9 *device)
2981 {
2982     IDirect3DTexture9 *texture = NULL;
2983     IDirect3DSurface9 *surface = NULL;
2984     HRESULT hr;
2985     DWORD color;
2986     const float quads[] = {
2987         -1.0,   -1.0,   0.0,    0.0,    0.0,
2988         -1.0,    0.0,   0.0,    0.0,    1.0,
2989          0.0,   -1.0,   0.0,    1.0,    0.0,
2990          0.0,    0.0,   0.0,    1.0,    1.0,
2991
2992          0.0,   -1.0,   0.0,    0.0,    0.0,
2993          0.0,    0.0,   0.0,    0.0,    1.0,
2994          1.0,   -1.0,   0.0,    1.0,    0.0,
2995          1.0,    0.0,   0.0,    1.0,    1.0,
2996
2997          0.0,    0.0,   0.0,    0.0,    0.0,
2998          0.0,    1.0,   0.0,    0.0,    1.0,
2999          1.0,    0.0,   0.0,    1.0,    0.0,
3000          1.0,    1.0,   0.0,    1.0,    1.0,
3001
3002         -1.0,    0.0,   0.0,    0.0,    0.0,
3003         -1.0,    1.0,   0.0,    0.0,    1.0,
3004          0.0,    0.0,   0.0,    1.0,    0.0,
3005          0.0,    1.0,   0.0,    1.0,    1.0,
3006     };
3007
3008     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3009     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3010
3011     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3012                                         &texture, NULL);
3013     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3014     if(!texture)
3015     {
3016         skip("Failed to create test texture\n");
3017         return;
3018     }
3019
3020     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3021     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3022     fill_surface(surface, 0xffff0000);
3023     IDirect3DSurface9_Release(surface);
3024     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3025     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3026     fill_surface(surface, 0xff00ff00);
3027     IDirect3DSurface9_Release(surface);
3028     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3029     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3030     fill_surface(surface, 0xff0000ff);
3031     IDirect3DSurface9_Release(surface);
3032
3033     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3034     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3035     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3036     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3037
3038     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3039     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3040
3041     hr = IDirect3DDevice9_BeginScene(device);
3042     if(SUCCEEDED(hr))
3043     {
3044         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3045         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3046         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3047         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3048
3049         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3050         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3051         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3052         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3053
3054         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3055         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3057         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3058
3059         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3060         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063         hr = IDirect3DDevice9_EndScene(device);
3064         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3065     }
3066
3067     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3068     color = getPixelColor(device, 160, 360);
3069     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
3070     color = getPixelColor(device, 160, 120);
3071     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
3072     color = getPixelColor(device, 480, 120);
3073     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
3074     color = getPixelColor(device, 480, 360);
3075     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
3076     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3077     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3078
3079     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3080     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3081
3082     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3083     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084
3085     hr = IDirect3DDevice9_BeginScene(device);
3086     if(SUCCEEDED(hr))
3087     {
3088         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3089         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3090         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3091         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3092
3093         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3094         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3095         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3096         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3097
3098         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3099         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3100         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3101         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3102
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107         hr = IDirect3DDevice9_EndScene(device);
3108         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3109     }
3110
3111     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3112      * samples from the highest level in the texture(level 2)
3113      */
3114     color = getPixelColor(device, 160, 360);
3115     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
3116     color = getPixelColor(device, 160, 120);
3117     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
3118     color = getPixelColor(device, 480, 120);
3119     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
3120     color = getPixelColor(device, 480, 360);
3121     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
3122     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3123     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3124
3125     hr = IDirect3DDevice9_BeginScene(device);
3126     if(SUCCEEDED(hr))
3127     {
3128         DWORD ret;
3129
3130         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. 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, 0);
3134         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3135         ret = IDirect3DTexture9_SetLOD(texture, 1);
3136         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3137         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
3138         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3139
3140         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3141         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3142         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3143         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3144         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3145         ret = IDirect3DTexture9_SetLOD(texture, 2);
3146         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3147         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
3148         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3149
3150         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3151         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153         ret = IDirect3DTexture9_SetLOD(texture, 1);
3154         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
3156         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3157
3158         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3159         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3160         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3162         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163         ret = IDirect3DTexture9_SetLOD(texture, 1);
3164         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
3166         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167         hr = IDirect3DDevice9_EndScene(device);
3168     }
3169
3170     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
3171      * samples from the highest level in the texture(level 2)
3172      */
3173     color = getPixelColor(device, 160, 360);
3174     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
3175     color = getPixelColor(device, 160, 120);
3176     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
3177     color = getPixelColor(device, 480, 120);
3178     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
3179     color = getPixelColor(device, 480, 360);
3180     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
3181     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3182     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3183
3184     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3185     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3187     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3189     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3190     IDirect3DTexture9_Release(texture);
3191 }
3192
3193 static void release_buffer_test(IDirect3DDevice9 *device)
3194 {
3195     IDirect3DVertexBuffer9 *vb = NULL;
3196     IDirect3DIndexBuffer9 *ib = NULL;
3197     HRESULT hr;
3198     BYTE *data;
3199     LONG ref;
3200
3201     static const struct vertex quad[] = {
3202         {-1.0,      -1.0,       0.1,        0xffff0000},
3203         {-1.0,       1.0,       0.1,        0xffff0000},
3204         { 1.0,       1.0,       0.1,        0xffff0000},
3205
3206         {-1.0,      -1.0,       0.1,        0xff00ff00},
3207         {-1.0,       1.0,       0.1,        0xff00ff00},
3208         { 1.0,       1.0,       0.1,        0xff00ff00}
3209     };
3210     short indices[] = {3, 4, 5};
3211
3212     /* Index and vertex buffers should always be creatable */
3213     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3214                                               D3DPOOL_MANAGED, &vb, NULL);
3215     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3216     if(!vb) {
3217         skip("Failed to create a vertex buffer\n");
3218         return;
3219     }
3220     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3221     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3222     if(!ib) {
3223         skip("Failed to create an index buffer\n");
3224         return;
3225     }
3226
3227     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3228     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3229     memcpy(data, quad, sizeof(quad));
3230     hr = IDirect3DVertexBuffer9_Unlock(vb);
3231     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3232
3233     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3234     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3235     memcpy(data, indices, sizeof(indices));
3236     hr = IDirect3DIndexBuffer9_Unlock(ib);
3237     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3238
3239     hr = IDirect3DDevice9_SetIndices(device, ib);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3241     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3242     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3243     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3244     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3245
3246     /* Now destroy the bound index buffer and draw again */
3247     ref = IDirect3DIndexBuffer9_Release(ib);
3248     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3249
3250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3252
3253     hr = IDirect3DDevice9_BeginScene(device);
3254     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3255     if(SUCCEEDED(hr))
3256     {
3257         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3258          * making assumptions about the indices or vertices
3259          */
3260         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3261         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3262         hr = IDirect3DDevice9_EndScene(device);
3263         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3264     }
3265
3266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3268
3269     hr = IDirect3DDevice9_SetIndices(device, NULL);
3270     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3271     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3273
3274     /* Index buffer was already destroyed as part of the test */
3275     IDirect3DVertexBuffer9_Release(vb);
3276 }
3277
3278 static void float_texture_test(IDirect3DDevice9 *device)
3279 {
3280     IDirect3D9 *d3d = NULL;
3281     HRESULT hr;
3282     IDirect3DTexture9 *texture = NULL;
3283     D3DLOCKED_RECT lr;
3284     float *data;
3285     DWORD color;
3286     float quad[] = {
3287         -1.0,      -1.0,       0.1,     0.0,    0.0,
3288         -1.0,       1.0,       0.1,     0.0,    1.0,
3289          1.0,      -1.0,       0.1,     1.0,    0.0,
3290          1.0,       1.0,       0.1,     1.0,    1.0,
3291     };
3292
3293     memset(&lr, 0, sizeof(lr));
3294     IDirect3DDevice9_GetDirect3D(device, &d3d);
3295     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3296                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3297         skip("D3DFMT_R32F textures not supported\n");
3298         goto out;
3299     }
3300
3301     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3302                                         D3DPOOL_MANAGED, &texture, NULL);
3303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3304     if(!texture) {
3305         skip("Failed to create R32F texture\n");
3306         goto out;
3307     }
3308
3309     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3310     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3311     data = lr.pBits;
3312     *data = 0.0;
3313     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3314     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3315
3316     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3317     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3318
3319     hr = IDirect3DDevice9_BeginScene(device);
3320     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3321     if(SUCCEEDED(hr))
3322     {
3323         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3324         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3325
3326         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3327         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3328
3329         hr = IDirect3DDevice9_EndScene(device);
3330         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3331     }
3332     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3333     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3334
3335     color = getPixelColor(device, 240, 320);
3336     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3337
3338     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3340
3341 out:
3342     if(texture) IDirect3DTexture9_Release(texture);
3343     IDirect3D9_Release(d3d);
3344 }
3345
3346 static void g16r16_texture_test(IDirect3DDevice9 *device)
3347 {
3348     IDirect3D9 *d3d = NULL;
3349     HRESULT hr;
3350     IDirect3DTexture9 *texture = NULL;
3351     D3DLOCKED_RECT lr;
3352     DWORD *data;
3353     DWORD color;
3354     float quad[] = {
3355        -1.0,      -1.0,       0.1,     0.0,    0.0,
3356        -1.0,       1.0,       0.1,     0.0,    1.0,
3357         1.0,      -1.0,       0.1,     1.0,    0.0,
3358         1.0,       1.0,       0.1,     1.0,    1.0,
3359     };
3360
3361     memset(&lr, 0, sizeof(lr));
3362     IDirect3DDevice9_GetDirect3D(device, &d3d);
3363     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3364        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3365            skip("D3DFMT_G16R16 textures not supported\n");
3366            goto out;
3367     }
3368
3369     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3370                                         D3DPOOL_MANAGED, &texture, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3372     if(!texture) {
3373         skip("Failed to create D3DFMT_G16R16 texture\n");
3374         goto out;
3375     }
3376
3377     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3378     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3379     data = lr.pBits;
3380     *data = 0x0f00f000;
3381     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3382     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3383
3384     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3385     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3386
3387     hr = IDirect3DDevice9_BeginScene(device);
3388     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3389     if(SUCCEEDED(hr))
3390     {
3391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3393
3394         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3395         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3396
3397         hr = IDirect3DDevice9_EndScene(device);
3398         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3399     }
3400     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3401     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3402
3403     color = getPixelColor(device, 240, 320);
3404     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3405        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3406
3407     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3408     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3409
3410 out:
3411     if(texture) IDirect3DTexture9_Release(texture);
3412     IDirect3D9_Release(d3d);
3413 }
3414
3415 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3416 {
3417     HRESULT hr;
3418     IDirect3D9 *d3d;
3419     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3420     D3DCAPS9 caps;
3421     IDirect3DTexture9 *texture = NULL;
3422     IDirect3DVolumeTexture9 *volume = NULL;
3423     unsigned int x, y, z;
3424     D3DLOCKED_RECT lr;
3425     D3DLOCKED_BOX lb;
3426     DWORD color;
3427     UINT w, h;
3428     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3429     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3430                            0.0, 1.0, 0.0, 0.0,
3431                            0.0, 0.0, 1.0, 0.0,
3432                            0.0, 0.0, 0.0, 1.0};
3433     static const D3DVERTEXELEMENT9 decl_elements[] = {
3434         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3435         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3436         D3DDECL_END()
3437     };
3438     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3439         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3440         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3441         D3DDECL_END()
3442     };
3443     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3444         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3445         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3446         D3DDECL_END()
3447     };
3448     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3449                                                  0x00, 0xff, 0x00, 0x00,
3450                                                  0x00, 0x00, 0x00, 0x00,
3451                                                  0x00, 0x00, 0x00, 0x00};
3452
3453     memset(&lr, 0, sizeof(lr));
3454     memset(&lb, 0, sizeof(lb));
3455     IDirect3DDevice9_GetDirect3D(device, &d3d);
3456     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3457                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3458         fmt = D3DFMT_A16B16G16R16;
3459     }
3460     IDirect3D9_Release(d3d);
3461
3462     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3464     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3465     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3466     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3467     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3468     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3470     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3472     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3473     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3474     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3475     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3476     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3477     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3478     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3479     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3480     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3481     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3482     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3483     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3484     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3486
3487     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3489     w = min(1024, caps.MaxTextureWidth);
3490     h = min(1024, caps.MaxTextureHeight);
3491     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3492                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3493     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3494     if(!texture) {
3495         skip("Failed to create the test texture\n");
3496         return;
3497     }
3498
3499     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3500      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3501      * 1.0 in red and green for the x and y coords
3502      */
3503     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3504     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3505     for(y = 0; y < h; y++) {
3506         for(x = 0; x < w; x++) {
3507             double r_f = (double) y / (double) h;
3508             double g_f = (double) x / (double) w;
3509             if(fmt == D3DFMT_A16B16G16R16) {
3510                 unsigned short r, g;
3511                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3512                 r = (unsigned short) (r_f * 65536.0);
3513                 g = (unsigned short) (g_f * 65536.0);
3514                 dst[0] = r;
3515                 dst[1] = g;
3516                 dst[2] = 0;
3517                 dst[3] = 65535;
3518             } else {
3519                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3520                 unsigned char r = (unsigned char) (r_f * 255.0);
3521                 unsigned char g = (unsigned char) (g_f * 255.0);
3522                 dst[0] = 0;
3523                 dst[1] = g;
3524                 dst[2] = r;
3525                 dst[3] = 255;
3526             }
3527         }
3528     }
3529     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3530     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3531     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3532     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3533
3534     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3535     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3536     hr = IDirect3DDevice9_BeginScene(device);
3537     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3538     if(SUCCEEDED(hr))
3539     {
3540         float quad1[] = {
3541             -1.0,      -1.0,       0.1,     1.0,    1.0,
3542             -1.0,       0.0,       0.1,     1.0,    1.0,
3543              0.0,      -1.0,       0.1,     1.0,    1.0,
3544              0.0,       0.0,       0.1,     1.0,    1.0,
3545         };
3546         float quad2[] = {
3547             -1.0,       0.0,       0.1,     1.0,    1.0,
3548             -1.0,       1.0,       0.1,     1.0,    1.0,
3549              0.0,       0.0,       0.1,     1.0,    1.0,
3550              0.0,       1.0,       0.1,     1.0,    1.0,
3551         };
3552         float quad3[] = {
3553              0.0,       0.0,       0.1,     0.5,    0.5,
3554              0.0,       1.0,       0.1,     0.5,    0.5,
3555              1.0,       0.0,       0.1,     0.5,    0.5,
3556              1.0,       1.0,       0.1,     0.5,    0.5,
3557         };
3558         float quad4[] = {
3559              320,       480,       0.1,     1.0,    0.0,    1.0,
3560              320,       240,       0.1,     1.0,    0.0,    1.0,
3561              640,       480,       0.1,     1.0,    0.0,    1.0,
3562              640,       240,       0.1,     1.0,    0.0,    1.0,
3563         };
3564         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3565                           0.0, 0.0, 0.0, 0.0,
3566                           0.0, 0.0, 0.0, 0.0,
3567                           0.0, 0.0, 0.0, 0.0};
3568
3569         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3570         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3571         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3572         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3573         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3574
3575         /* What happens with transforms enabled? */
3576         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3577         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3579         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3580
3581         /* What happens if 4 coords are used, but only 2 given ?*/
3582         mat[8] = 1.0;
3583         mat[13] = 1.0;
3584         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3585         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3586         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3587         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3588         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3589         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3590
3591         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3592          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3593          * due to the coords in the vertices. (turns out red, indeed)
3594          */
3595         memset(mat, 0, sizeof(mat));
3596         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3597         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3598         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3599         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3600         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3601         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3603         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3604
3605         hr = IDirect3DDevice9_EndScene(device);
3606         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3607     }
3608     color = getPixelColor(device, 160, 360);
3609     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3610     color = getPixelColor(device, 160, 120);
3611     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3612     color = getPixelColor(device, 480, 120);
3613     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3614     color = getPixelColor(device, 480, 360);
3615     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3616     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3617     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3618
3619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3620     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3621
3622     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3623     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3624     hr = IDirect3DDevice9_BeginScene(device);
3625     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3626     if(SUCCEEDED(hr))
3627     {
3628         float quad1[] = {
3629             -1.0,      -1.0,       0.1,     0.8,    0.2,
3630             -1.0,       0.0,       0.1,     0.8,    0.2,
3631              0.0,      -1.0,       0.1,     0.8,    0.2,
3632              0.0,       0.0,       0.1,     0.8,    0.2,
3633         };
3634         float quad2[] = {
3635             -1.0,       0.0,       0.1,     0.5,    1.0,
3636             -1.0,       1.0,       0.1,     0.5,    1.0,
3637              0.0,       0.0,       0.1,     0.5,    1.0,
3638              0.0,       1.0,       0.1,     0.5,    1.0,
3639         };
3640         float quad3[] = {
3641              0.0,       0.0,       0.1,     0.5,    1.0,
3642              0.0,       1.0,       0.1,     0.5,    1.0,
3643              1.0,       0.0,       0.1,     0.5,    1.0,
3644              1.0,       1.0,       0.1,     0.5,    1.0,
3645         };
3646         float quad4[] = {
3647              0.0,      -1.0,       0.1,     0.8,    0.2,
3648              0.0,       0.0,       0.1,     0.8,    0.2,
3649              1.0,      -1.0,       0.1,     0.8,    0.2,
3650              1.0,       0.0,       0.1,     0.8,    0.2,
3651         };
3652         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3653                           0.0, 0.0, 0.0, 0.0,
3654                           0.0, 1.0, 0.0, 0.0,
3655                           0.0, 0.0, 0.0, 0.0};
3656
3657         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3658          */
3659         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3660         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3661         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3662         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3663
3664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3665         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3666
3667         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3668          * it behaves like COUNT2 because normal textures require 2 coords
3669          */
3670         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3671         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3672         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3673         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3674
3675         /* Just to be sure, the same as quad2 above */
3676         memset(mat, 0, sizeof(mat));
3677         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3678         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3679         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3680         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3682         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3683
3684         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3685          * used? And what happens to the first?
3686          */
3687         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3688         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3689         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3690         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3691
3692         hr = IDirect3DDevice9_EndScene(device);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3694     }
3695     color = getPixelColor(device, 160, 360);
3696     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3697     color = getPixelColor(device, 160, 120);
3698     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3699     color = getPixelColor(device, 480, 120);
3700     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3701        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3702     color = getPixelColor(device, 480, 360);
3703     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3704        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3707
3708     IDirect3DTexture9_Release(texture);
3709
3710     /* Test projected textures, without any fancy matrices */
3711     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3712     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3713     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3714     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3715     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3716     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3718     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3719
3720     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3721     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3722     for(x = 0; x < 4; x++) {
3723         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3724     }
3725     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3726     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3727     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3728     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3729
3730     hr = IDirect3DDevice9_BeginScene(device);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3732     if(SUCCEEDED(hr))
3733     {
3734         const float proj_quads[] = {
3735            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3736             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3737            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3738             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3739            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3740             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3741            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3742             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3743         };
3744
3745         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3746         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3747         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3748         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3749
3750         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3751         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3752         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3753         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3754
3755         hr = IDirect3DDevice9_EndScene(device);
3756         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3757     }
3758
3759     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3760     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3761     IDirect3DTexture9_Release(texture);
3762
3763     color = getPixelColor(device, 158, 118);
3764     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3765     color = getPixelColor(device, 162, 118);
3766     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3767     color = getPixelColor(device, 158, 122);
3768     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3769     color = getPixelColor(device, 162, 122);
3770     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3771
3772     color = getPixelColor(device, 158, 178);
3773     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3774     color = getPixelColor(device, 162, 178);
3775     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3776     color = getPixelColor(device, 158, 182);
3777     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3778     color = getPixelColor(device, 162, 182);
3779     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3780
3781     color = getPixelColor(device, 318, 118);
3782     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3783     color = getPixelColor(device, 322, 118);
3784     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3785     color = getPixelColor(device, 318, 122);
3786     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3787     color = getPixelColor(device, 322, 122);
3788     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3789
3790     color = getPixelColor(device, 318, 178);
3791     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3792     color = getPixelColor(device, 322, 178);
3793     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3794     color = getPixelColor(device, 318, 182);
3795     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3796     color = getPixelColor(device, 322, 182);
3797     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3798
3799     color = getPixelColor(device, 238, 298);
3800     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3801     color = getPixelColor(device, 242, 298);
3802     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 238, 302);
3804     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 242, 302);
3806     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3807
3808     color = getPixelColor(device, 238, 388);
3809     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3810     color = getPixelColor(device, 242, 388);
3811     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3812     color = getPixelColor(device, 238, 392);
3813     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3814     color = getPixelColor(device, 242, 392);
3815     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3816
3817     color = getPixelColor(device, 478, 298);
3818     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3819     color = getPixelColor(device, 482, 298);
3820     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 478, 302);
3822     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3823     color = getPixelColor(device, 482, 302);
3824     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3825
3826     color = getPixelColor(device, 478, 388);
3827     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3828     color = getPixelColor(device, 482, 388);
3829     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3830     color = getPixelColor(device, 478, 392);
3831     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 482, 392);
3833     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3834
3835     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3836     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3837
3838     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3839     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3840     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3841      * Thus watch out if sampling from texels between 0 and 1.
3842      */
3843     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3844     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3845        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3846     if(!volume) {
3847         skip("Failed to create a volume texture\n");
3848         goto out;
3849     }
3850
3851     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3852     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3853     for(z = 0; z < 32; z++) {
3854         for(y = 0; y < 32; y++) {
3855             for(x = 0; x < 32; x++) {
3856                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3857                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3858                 float r_f = (float) x / 31.0;
3859                 float g_f = (float) y / 31.0;
3860                 float b_f = (float) z / 31.0;
3861
3862                 if(fmt == D3DFMT_A16B16G16R16) {
3863                     unsigned short *mem_s = mem;
3864                     mem_s[0]  = r_f * 65535.0;
3865                     mem_s[1]  = g_f * 65535.0;
3866                     mem_s[2]  = b_f * 65535.0;
3867                     mem_s[3]  = 65535;
3868                 } else {
3869                     unsigned char *mem_c = mem;
3870                     mem_c[0]  = b_f * 255.0;
3871                     mem_c[1]  = g_f * 255.0;
3872                     mem_c[2]  = r_f * 255.0;
3873                     mem_c[3]  = 255;
3874                 }
3875             }
3876         }
3877     }
3878     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3879     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3880
3881     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3882     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3883
3884     hr = IDirect3DDevice9_BeginScene(device);
3885     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3886     if(SUCCEEDED(hr))
3887     {
3888         float quad1[] = {
3889             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3890             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3891              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3892              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3893         };
3894         float quad2[] = {
3895             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3896             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3897              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3898              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3899         };
3900         float quad3[] = {
3901              0.0,       0.0,       0.1,     0.0,    0.0,
3902              0.0,       1.0,       0.1,     0.0,    0.0,
3903              1.0,       0.0,       0.1,     0.0,    0.0,
3904              1.0,       1.0,       0.1,     0.0,    0.0
3905         };
3906         float quad4[] = {
3907              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3908              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3909              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3910              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3911         };
3912         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3913                          0.0, 0.0, 1.0, 0.0,
3914                          0.0, 1.0, 0.0, 0.0,
3915                          0.0, 0.0, 0.0, 1.0};
3916         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3917         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3918
3919         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3920          * values
3921          */
3922         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3923         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3924         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3927         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3928
3929         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3930          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3931          * otherwise the w will be missing(blue).
3932          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3933          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3934          */
3935         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3939
3940         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3941         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3942         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3949
3950         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3951          * disable. ATI extends it up to the amount of values needed for the volume texture
3952          */
3953         memset(mat, 0, sizeof(mat));
3954         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3956         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3957         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3958         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3959         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3960         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3961         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3962
3963         hr = IDirect3DDevice9_EndScene(device);
3964         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3965     }
3966
3967     color = getPixelColor(device, 160, 360);
3968     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3969     color = getPixelColor(device, 160, 120);
3970     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3971        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3972     color = getPixelColor(device, 480, 120);
3973     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3974     color = getPixelColor(device, 480, 360);
3975     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3976
3977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3979
3980     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3981     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3982     hr = IDirect3DDevice9_BeginScene(device);
3983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3984     if(SUCCEEDED(hr))
3985     {
3986         float quad1[] = {
3987             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3988             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3989              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3990              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3991         };
3992         float quad2[] = {
3993             -1.0,       0.0,       0.1,
3994             -1.0,       1.0,       0.1,
3995              0.0,       0.0,       0.1,
3996              0.0,       1.0,       0.1,
3997         };
3998         float quad3[] = {
3999              0.0,       0.0,       0.1,     1.0,
4000              0.0,       1.0,       0.1,     1.0,
4001              1.0,       0.0,       0.1,     1.0,
4002              1.0,       1.0,       0.1,     1.0
4003         };
4004         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4005                            0.0, 0.0, 0.0, 0.0,
4006                            0.0, 0.0, 0.0, 0.0,
4007                            0.0, 1.0, 0.0, 0.0};
4008         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4009                            1.0, 0.0, 0.0, 0.0,
4010                            0.0, 1.0, 0.0, 0.0,
4011                            0.0, 0.0, 1.0, 0.0};
4012         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4014
4015         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4016          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4017          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4018          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4019          * 4th *input* coordinate.
4020          */
4021         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4022         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4023         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4024         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4025         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4026         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4027
4028         /* None passed */
4029         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4030         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4031         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4032         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4033         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4034         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4035
4036         /* 4 used, 1 passed */
4037         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4038         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4039         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4040         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4041         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4042         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4043
4044         hr = IDirect3DDevice9_EndScene(device);
4045         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4046     }
4047     color = getPixelColor(device, 160, 360);
4048     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4049     color = getPixelColor(device, 160, 120);
4050     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4051     color = getPixelColor(device, 480, 120);
4052     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4053     /* Quad4: unused */
4054
4055     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4056     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4057
4058     IDirect3DVolumeTexture9_Release(volume);
4059
4060     out:
4061     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4062     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4063     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4064     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4065     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4066     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4067     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4068     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4069     IDirect3DVertexDeclaration9_Release(decl);
4070     IDirect3DVertexDeclaration9_Release(decl2);
4071     IDirect3DVertexDeclaration9_Release(decl3);
4072 }
4073
4074 static void texdepth_test(IDirect3DDevice9 *device)
4075 {
4076     IDirect3DPixelShader9 *shader;
4077     HRESULT hr;
4078     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4079     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4080     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4081     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4082     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4083     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4084     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4085     DWORD shader_code[] = {
4086         0xffff0104,                                                                 /* ps_1_4               */
4087         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4088         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4089         0x0000fffd,                                                                 /* phase                */
4090         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4091         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4092         0x0000ffff                                                                  /* end                  */
4093     };
4094     DWORD color;
4095     float vertex[] = {
4096        -1.0,   -1.0,    0.0,
4097         1.0,   -1.0,    1.0,
4098        -1.0,    1.0,    0.0,
4099         1.0,    1.0,    1.0
4100     };
4101
4102     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4103     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4104
4105     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4107     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4108     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4109     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4110     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4113     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4114     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4115
4116     /* Fill the depth buffer with a gradient */
4117     hr = IDirect3DDevice9_BeginScene(device);
4118     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4119     if(SUCCEEDED(hr))
4120     {
4121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4122         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4123         hr = IDirect3DDevice9_EndScene(device);
4124         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4125     }
4126
4127     /* Now perform the actual tests. Same geometry, but with the shader */
4128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4132     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4133     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4134
4135     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4136     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4137     hr = IDirect3DDevice9_BeginScene(device);
4138     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4139     if(SUCCEEDED(hr))
4140     {
4141         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4142         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4143
4144         hr = IDirect3DDevice9_EndScene(device);
4145         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4146     }
4147
4148     color = getPixelColor(device, 158, 240);
4149     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4150     color = getPixelColor(device, 162, 240);
4151     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4152
4153     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4154     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4155
4156     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4157     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4158
4159     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4160     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4161     hr = IDirect3DDevice9_BeginScene(device);
4162     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4163     if(SUCCEEDED(hr))
4164     {
4165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4166         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4167
4168         hr = IDirect3DDevice9_EndScene(device);
4169         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4170     }
4171
4172     color = getPixelColor(device, 318, 240);
4173     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4174     color = getPixelColor(device, 322, 240);
4175     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4176
4177     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4178     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4179
4180     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4181     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4182
4183     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4184     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4185     hr = IDirect3DDevice9_BeginScene(device);
4186     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4187     if(SUCCEEDED(hr))
4188     {
4189         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4190         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4191
4192         hr = IDirect3DDevice9_EndScene(device);
4193         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4194     }
4195
4196     color = getPixelColor(device, 1, 240);
4197     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4198
4199     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4200     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4201
4202     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4203     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4204
4205     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4206     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4207     hr = IDirect3DDevice9_BeginScene(device);
4208     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4209     if(SUCCEEDED(hr))
4210     {
4211         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4212         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4213
4214         hr = IDirect3DDevice9_EndScene(device);
4215         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4216     }
4217     color = getPixelColor(device, 318, 240);
4218     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4219     color = getPixelColor(device, 322, 240);
4220     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4221
4222     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4223     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4224
4225     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4226     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4227
4228     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4229     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4230     hr = IDirect3DDevice9_BeginScene(device);
4231     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4232     if(SUCCEEDED(hr))
4233     {
4234         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4235         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4236
4237         hr = IDirect3DDevice9_EndScene(device);
4238         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4239     }
4240
4241     color = getPixelColor(device, 1, 240);
4242     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4243
4244     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4245     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4246
4247     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4248     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4249
4250     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4252     hr = IDirect3DDevice9_BeginScene(device);
4253     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4254     if(SUCCEEDED(hr))
4255     {
4256         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4257         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4258
4259         hr = IDirect3DDevice9_EndScene(device);
4260         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4261     }
4262
4263     color = getPixelColor(device, 638, 240);
4264     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4265
4266     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4268
4269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4270     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4271
4272     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4273     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4274     hr = IDirect3DDevice9_BeginScene(device);
4275     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4276     if(SUCCEEDED(hr))
4277     {
4278         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4279         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4280
4281         hr = IDirect3DDevice9_EndScene(device);
4282         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4283     }
4284
4285     color = getPixelColor(device, 638, 240);
4286     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4287
4288     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4290
4291     /* Cleanup */
4292     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4293     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4294     IDirect3DPixelShader9_Release(shader);
4295
4296     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4297     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4298     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4299     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4300 }
4301
4302 static void texkill_test(IDirect3DDevice9 *device)
4303 {
4304     IDirect3DPixelShader9 *shader;
4305     HRESULT hr;
4306     DWORD color;
4307
4308     const float vertex[] = {
4309     /*                          bottom  top    right    left */
4310         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4311          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4312         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4313          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4314     };
4315
4316     DWORD shader_code_11[] = {
4317     0xffff0101,                                                             /* ps_1_1                     */
4318     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4319     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4320     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4321     0x0000ffff                                                              /* end                        */
4322     };
4323     DWORD shader_code_20[] = {
4324     0xffff0200,                                                             /* ps_2_0                     */
4325     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4326     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4327     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4328     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4329     0x0000ffff                                                              /* end                        */
4330     };
4331
4332     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4333     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4334     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4335     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4336
4337     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4338     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4339     hr = IDirect3DDevice9_BeginScene(device);
4340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4341     if(SUCCEEDED(hr))
4342     {
4343         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4344         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4346         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4347         hr = IDirect3DDevice9_EndScene(device);
4348         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4349     }
4350     color = getPixelColor(device, 63, 46);
4351     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4352     color = getPixelColor(device, 66, 46);
4353     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4354     color = getPixelColor(device, 63, 49);
4355     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4356     color = getPixelColor(device, 66, 49);
4357     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4358
4359     color = getPixelColor(device, 578, 46);
4360     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4361     color = getPixelColor(device, 575, 46);
4362     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4363     color = getPixelColor(device, 578, 49);
4364     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4365     color = getPixelColor(device, 575, 49);
4366     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4367
4368     color = getPixelColor(device, 63, 430);
4369     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4370     color = getPixelColor(device, 63, 433);
4371     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4372     color = getPixelColor(device, 66, 433);
4373     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4374     color = getPixelColor(device, 66, 430);
4375     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4376
4377     color = getPixelColor(device, 578, 430);
4378     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4379     color = getPixelColor(device, 578, 433);
4380     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4381     color = getPixelColor(device, 575, 433);
4382     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4383     color = getPixelColor(device, 575, 430);
4384     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4385
4386     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4387     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4388
4389     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4390     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4391     IDirect3DPixelShader9_Release(shader);
4392
4393     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4394     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4395     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4396     if(FAILED(hr)) {
4397         skip("Failed to create 2.0 test shader, most likely not supported\n");
4398         return;
4399     }
4400
4401     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4402     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4403     hr = IDirect3DDevice9_BeginScene(device);
4404     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4405     if(SUCCEEDED(hr))
4406     {
4407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4409         hr = IDirect3DDevice9_EndScene(device);
4410         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4411     }
4412
4413     color = getPixelColor(device, 63, 46);
4414     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4415     color = getPixelColor(device, 66, 46);
4416     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4417     color = getPixelColor(device, 63, 49);
4418     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4419     color = getPixelColor(device, 66, 49);
4420     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4421
4422     color = getPixelColor(device, 578, 46);
4423     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4424     color = getPixelColor(device, 575, 46);
4425     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4426     color = getPixelColor(device, 578, 49);
4427     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4428     color = getPixelColor(device, 575, 49);
4429     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4430
4431     color = getPixelColor(device, 63, 430);
4432     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4433     color = getPixelColor(device, 63, 433);
4434     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4435     color = getPixelColor(device, 66, 433);
4436     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4437     color = getPixelColor(device, 66, 430);
4438     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4439
4440     color = getPixelColor(device, 578, 430);
4441     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4442     color = getPixelColor(device, 578, 433);
4443     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4444     color = getPixelColor(device, 575, 433);
4445     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4446     color = getPixelColor(device, 575, 430);
4447     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4448
4449     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4450     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4451
4452     /* Cleanup */
4453     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4454     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4455     IDirect3DPixelShader9_Release(shader);
4456 }
4457
4458 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4459 {
4460     IDirect3D9 *d3d9;
4461     HRESULT hr;
4462     IDirect3DTexture9 *texture;
4463     IDirect3DPixelShader9 *shader;
4464     IDirect3DPixelShader9 *shader2;
4465     D3DLOCKED_RECT lr;
4466     DWORD color;
4467     DWORD shader_code[] = {
4468         0xffff0101,                             /* ps_1_1       */
4469         0x00000042, 0xb00f0000,                 /* tex t0       */
4470         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4471         0x0000ffff                              /* end          */
4472     };
4473     DWORD shader_code2[] = {
4474         0xffff0101,                             /* ps_1_1       */
4475         0x00000042, 0xb00f0000,                 /* tex t0       */
4476         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4477         0x0000ffff                              /* end          */
4478     };
4479
4480     float quad[] = {
4481        -1.0,   -1.0,   0.1,     0.5,    0.5,
4482         1.0,   -1.0,   0.1,     0.5,    0.5,
4483        -1.0,    1.0,   0.1,     0.5,    0.5,
4484         1.0,    1.0,   0.1,     0.5,    0.5,
4485     };
4486
4487     memset(&lr, 0, sizeof(lr));
4488     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4489     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4490                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4491     IDirect3D9_Release(d3d9);
4492     if(FAILED(hr)) {
4493         skip("No D3DFMT_X8L8V8U8 support\n");
4494         return;
4495     };
4496
4497     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4498     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4499
4500     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4501     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4502     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4503     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4504     *((DWORD *) lr.pBits) = 0x11ca3141;
4505     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4506     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4507
4508     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4510     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4511     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4512
4513     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4515     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4517     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4518     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4519
4520     hr = IDirect3DDevice9_BeginScene(device);
4521     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4522     if(SUCCEEDED(hr))
4523     {
4524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4525         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4526
4527         hr = IDirect3DDevice9_EndScene(device);
4528         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4529     }
4530     color = getPixelColor(device, 578, 430);
4531     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4532        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4533     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4534     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4535
4536     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4537     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4538     hr = IDirect3DDevice9_BeginScene(device);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4540     if(SUCCEEDED(hr))
4541     {
4542         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4543         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4544
4545         hr = IDirect3DDevice9_EndScene(device);
4546         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4547     }
4548     color = getPixelColor(device, 578, 430);
4549     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4550     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4551     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4552
4553     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4554     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4557     IDirect3DPixelShader9_Release(shader);
4558     IDirect3DPixelShader9_Release(shader2);
4559     IDirect3DTexture9_Release(texture);
4560 }
4561
4562 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4563 {
4564     HRESULT hr;
4565     IDirect3D9 *d3d;
4566     IDirect3DTexture9 *texture = NULL;
4567     IDirect3DSurface9 *surface;
4568     DWORD color;
4569     const RECT r1 = {256, 256, 512, 512};
4570     const RECT r2 = {512, 256, 768, 512};
4571     const RECT r3 = {256, 512, 512, 768};
4572     const RECT r4 = {512, 512, 768, 768};
4573     unsigned int x, y;
4574     D3DLOCKED_RECT lr;
4575     memset(&lr, 0, sizeof(lr));
4576
4577     IDirect3DDevice9_GetDirect3D(device, &d3d);
4578     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4579        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4580         skip("No autogenmipmap support\n");
4581         IDirect3D9_Release(d3d);
4582         return;
4583     }
4584     IDirect3D9_Release(d3d);
4585
4586     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4587     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4588
4589     /* Make the mipmap big, so that a smaller mipmap is used
4590      */
4591     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4592                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4593     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4594
4595     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4596     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4597     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4598     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4599     for(y = 0; y < 1024; y++) {
4600         for(x = 0; x < 1024; x++) {
4601             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4602             POINT pt;
4603
4604             pt.x = x;
4605             pt.y = y;
4606             if(PtInRect(&r1, pt)) {
4607                 *dst = 0xffff0000;
4608             } else if(PtInRect(&r2, pt)) {
4609                 *dst = 0xff00ff00;
4610             } else if(PtInRect(&r3, pt)) {
4611                 *dst = 0xff0000ff;
4612             } else if(PtInRect(&r4, pt)) {
4613                 *dst = 0xff000000;
4614             } else {
4615                 *dst = 0xffffffff;
4616             }
4617         }
4618     }
4619     hr = IDirect3DSurface9_UnlockRect(surface);
4620     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4621     IDirect3DSurface9_Release(surface);
4622
4623     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4625     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4626     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4627
4628     hr = IDirect3DDevice9_BeginScene(device);
4629     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4630     if(SUCCEEDED(hr)) {
4631         const float quad[] =  {
4632            -0.5,   -0.5,    0.1,    0.0,    0.0,
4633            -0.5,    0.5,    0.1,    0.0,    1.0,
4634             0.5,   -0.5,    0.1,    1.0,    0.0,
4635             0.5,    0.5,    0.1,    1.0,    1.0
4636         };
4637
4638         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4639         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4641         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4642         hr = IDirect3DDevice9_EndScene(device);
4643         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4644     }
4645     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4646     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4647     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4649     IDirect3DTexture9_Release(texture);
4650
4651     color = getPixelColor(device, 200, 200);
4652     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4653     color = getPixelColor(device, 280, 200);
4654     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4655     color = getPixelColor(device, 360, 200);
4656     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4657     color = getPixelColor(device, 440, 200);
4658     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4659     color = getPixelColor(device, 200, 270);
4660     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4661     color = getPixelColor(device, 280, 270);
4662     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4663     color = getPixelColor(device, 360, 270);
4664     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4665     color = getPixelColor(device, 440, 270);
4666     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4667     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4668     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4669 }
4670
4671 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4672 {
4673     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4674     IDirect3DVertexDeclaration9 *decl;
4675     HRESULT hr;
4676     DWORD color;
4677     DWORD shader_code_11[] =  {
4678         0xfffe0101,                                         /* vs_1_1           */
4679         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4680         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4681         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4682         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4683         0x0000ffff                                          /* end              */
4684     };
4685     DWORD shader_code_11_2[] =  {
4686         0xfffe0101,                                         /* vs_1_1           */
4687         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4688         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4689         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4690         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4691         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4692         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4693         0x0000ffff                                          /* end              */
4694     };
4695     DWORD shader_code_20[] =  {
4696         0xfffe0200,                                         /* vs_2_0           */
4697         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4698         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4699         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4700         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4701         0x0000ffff                                          /* end              */
4702     };
4703     DWORD shader_code_20_2[] =  {
4704         0xfffe0200,                                         /* vs_2_0           */
4705         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4706         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4707         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4708         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4709         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4710         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4711         0x0000ffff                                          /* end              */
4712     };
4713     static const D3DVERTEXELEMENT9 decl_elements[] = {
4714         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4715         D3DDECL_END()
4716     };
4717     float quad1[] = {
4718         -1.0,   -1.0,   0.1,
4719          0.0,   -1.0,   0.1,
4720         -1.0,    0.0,   0.1,
4721          0.0,    0.0,   0.1
4722     };
4723     float quad2[] = {
4724          0.0,   -1.0,   0.1,
4725          1.0,   -1.0,   0.1,
4726          0.0,    0.0,   0.1,
4727          1.0,    0.0,   0.1
4728     };
4729     float quad3[] = {
4730          0.0,    0.0,   0.1,
4731          1.0,    0.0,   0.1,
4732          0.0,    1.0,   0.1,
4733          1.0,    1.0,   0.1
4734     };
4735     float quad4[] = {
4736         -1.0,    0.0,   0.1,
4737          0.0,    0.0,   0.1,
4738         -1.0,    1.0,   0.1,
4739          0.0,    1.0,   0.1
4740     };
4741     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4742     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4743
4744     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4745     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4746
4747     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4748     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4749     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4750     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4751     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4752     if(FAILED(hr)) shader_20 = NULL;
4753     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4754     if(FAILED(hr)) shader_20_2 = NULL;
4755     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4756     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4757
4758     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4759     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4760     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4761     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4762     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4763     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4764
4765     hr = IDirect3DDevice9_BeginScene(device);
4766     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4767     if(SUCCEEDED(hr))
4768     {
4769         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4770         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4772         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4773
4774         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4775         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4776         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4777         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4778
4779         if(shader_20) {
4780             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4781             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4782             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4783             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4784         }
4785
4786         if(shader_20_2) {
4787             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4788             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4789             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4790             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4791         }
4792
4793         hr = IDirect3DDevice9_EndScene(device);
4794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4795     }
4796
4797     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4798     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4799     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4800     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4801
4802     color = getPixelColor(device, 160, 360);
4803     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4804        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4805     color = getPixelColor(device, 480, 360);
4806     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4807        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4808     if(shader_20) {
4809         color = getPixelColor(device, 160, 120);
4810         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4811            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4812     }
4813     if(shader_20_2) {
4814         color = getPixelColor(device, 480, 120);
4815         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4816            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4817     }
4818     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4819     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4820
4821     IDirect3DVertexDeclaration9_Release(decl);
4822     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4823     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4824     IDirect3DVertexShader9_Release(shader_11_2);
4825     IDirect3DVertexShader9_Release(shader_11);
4826 }
4827
4828 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4829 {
4830     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4831     HRESULT hr;
4832     DWORD color;
4833     DWORD shader_code_11[] =  {
4834         0xffff0101,                                         /* ps_1_1           */
4835         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4836         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4837         0x0000ffff                                          /* end              */
4838     };
4839     DWORD shader_code_12[] =  {
4840         0xffff0102,                                         /* ps_1_2           */
4841         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4842         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4843         0x0000ffff                                          /* end              */
4844     };
4845     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4846      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4847      * During development of this test, 1.3 shaders were verified too
4848      */
4849     DWORD shader_code_14[] =  {
4850         0xffff0104,                                         /* ps_1_4           */
4851         /* Try to make one constant local. It gets clamped too, although the binary contains
4852          * the bigger numbers
4853          */
4854         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4855         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4856         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4857         0x0000ffff                                          /* end              */
4858     };
4859     DWORD shader_code_20[] =  {
4860         0xffff0200,                                         /* ps_2_0           */
4861         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4862         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4863         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4864         0x0000ffff                                          /* end              */
4865     };
4866     float quad1[] = {
4867         -1.0,   -1.0,   0.1,
4868          0.0,   -1.0,   0.1,
4869         -1.0,    0.0,   0.1,
4870          0.0,    0.0,   0.1
4871     };
4872     float quad2[] = {
4873          0.0,   -1.0,   0.1,
4874          1.0,   -1.0,   0.1,
4875          0.0,    0.0,   0.1,
4876          1.0,    0.0,   0.1
4877     };
4878     float quad3[] = {
4879          0.0,    0.0,   0.1,
4880          1.0,    0.0,   0.1,
4881          0.0,    1.0,   0.1,
4882          1.0,    1.0,   0.1
4883     };
4884     float quad4[] = {
4885         -1.0,    0.0,   0.1,
4886          0.0,    0.0,   0.1,
4887         -1.0,    1.0,   0.1,
4888          0.0,    1.0,   0.1
4889     };
4890     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4891     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4892
4893     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4894     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4895
4896     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4897     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4898     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4899     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4900     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4901     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4902     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4903     if(FAILED(hr)) shader_20 = NULL;
4904
4905     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4906     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4907     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4908     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4910     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4911
4912     hr = IDirect3DDevice9_BeginScene(device);
4913     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4914     if(SUCCEEDED(hr))
4915     {
4916         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4917         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4919         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4920
4921         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4922         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4923         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4924         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4925
4926         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4927         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4928         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4929         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4930
4931         if(shader_20) {
4932             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4933             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4934             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4935             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4936         }
4937
4938         hr = IDirect3DDevice9_EndScene(device);
4939         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4940     }
4941     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4942     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4943
4944     color = getPixelColor(device, 160, 360);
4945     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4946        "quad 1 has color %08x, expected 0x00808000\n", color);
4947     color = getPixelColor(device, 480, 360);
4948     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4949        "quad 2 has color %08x, expected 0x00808000\n", color);
4950     color = getPixelColor(device, 480, 120);
4951     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4952        "quad 3 has color %08x, expected 0x00808000\n", color);
4953     if(shader_20) {
4954         color = getPixelColor(device, 160, 120);
4955         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4956            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4957     }
4958     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4959     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4960
4961     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4962     IDirect3DPixelShader9_Release(shader_14);
4963     IDirect3DPixelShader9_Release(shader_12);
4964     IDirect3DPixelShader9_Release(shader_11);
4965 }
4966
4967 static void dp2add_ps_test(IDirect3DDevice9 *device)
4968 {
4969     IDirect3DPixelShader9 *shader_dp2add = NULL;
4970     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4971     HRESULT hr;
4972     DWORD color;
4973
4974     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4975      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4976      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4977      * r0 first.
4978      * The result here for the r,g,b components should be roughly 0.5:
4979      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4980     static const DWORD shader_code_dp2add[] =  {
4981         0xffff0200,                                                             /* ps_2_0                       */
4982         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4983
4984         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4985         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4986
4987         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4988         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4989         0x0000ffff                                                              /* end                          */
4990     };
4991
4992     /* Test the _sat modifier, too.  Result here should be:
4993      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4994      *      _SAT: ==> 1.0
4995      *   ADD: (1.0 + -0.5) = 0.5
4996      */
4997     static const DWORD shader_code_dp2add_sat[] =  {
4998         0xffff0200,                                                             /* ps_2_0                           */
4999         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5000
5001         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5002         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5003         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5004
5005         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5006         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5007         0x0000ffff                                                              /* end                              */
5008     };
5009
5010     const float quad[] = {
5011         -1.0,   -1.0,   0.1,
5012          1.0,   -1.0,   0.1,
5013         -1.0,    1.0,   0.1,
5014          1.0,    1.0,   0.1
5015     };
5016
5017
5018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5020
5021     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5022     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5023
5024     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5025     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5026
5027     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5028     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5029
5030     if (shader_dp2add) {
5031
5032         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5033         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5034
5035         hr = IDirect3DDevice9_BeginScene(device);
5036         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5037         if(SUCCEEDED(hr))
5038         {
5039             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5040             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5041
5042             hr = IDirect3DDevice9_EndScene(device);
5043             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5044         }
5045
5046         color = getPixelColor(device, 360, 240);
5047         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5048                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5049
5050         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5051         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5052
5053         IDirect3DPixelShader9_Release(shader_dp2add);
5054     } else {
5055         skip("dp2add shader creation failed\n");
5056     }
5057
5058     if (shader_dp2add_sat) {
5059
5060         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5061         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5062
5063         hr = IDirect3DDevice9_BeginScene(device);
5064         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5065         if(SUCCEEDED(hr))
5066         {
5067             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5068             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5069
5070             hr = IDirect3DDevice9_EndScene(device);
5071             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5072         }
5073
5074         color = getPixelColor(device, 360, 240);
5075         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5076                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5077
5078         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5079         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5080
5081         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5082     } else {
5083         skip("dp2add shader creation failed\n");
5084     }
5085
5086     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5087     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5088 }
5089
5090 static void cnd_test(IDirect3DDevice9 *device)
5091 {
5092     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5093     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5094     HRESULT hr;
5095     DWORD color;
5096     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5097      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5098      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5099      */
5100     DWORD shader_code_11[] =  {
5101         0xffff0101,                                                                 /* ps_1_1               */
5102         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5103         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5104         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5105         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5106         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5107         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5108         0x0000ffff                                                                  /* end                  */
5109     };
5110     DWORD shader_code_12[] =  {
5111         0xffff0102,                                                                 /* ps_1_2               */
5112         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5113         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5114         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5115         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5116         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5117         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5118         0x0000ffff                                                                  /* end                  */
5119     };
5120     DWORD shader_code_13[] =  {
5121         0xffff0103,                                                                 /* ps_1_3               */
5122         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5123         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5124         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5125         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5126         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5127         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5128         0x0000ffff                                                                  /* end                  */
5129     };
5130     DWORD shader_code_14[] =  {
5131         0xffff0104,                                                                 /* ps_1_3               */
5132         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5133         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5134         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5135         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5136         0x0000ffff                                                                  /* end                  */
5137     };
5138
5139     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5140      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5141      * set by the compiler, it was added manually after compilation. It isn't always allowed,
5142      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
5143      * native CreatePixelShader returns an error.
5144      *
5145      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5146      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5147      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5148      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5149      */
5150     DWORD shader_code_11_coissue[] =  {
5151         0xffff0101,                                                             /* ps_1_1                   */
5152         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5153         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5154         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5155         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5156         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5157         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5158         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5159         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5160         /* 0x40000000 = D3DSI_COISSUE */
5161         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5162         0x0000ffff                                                              /* end                      */
5163     };
5164     DWORD shader_code_12_coissue[] =  {
5165         0xffff0102,                                                             /* ps_1_2                   */
5166         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5167         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5168         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5169         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5170         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5171         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5172         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5173         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5174         /* 0x40000000 = D3DSI_COISSUE */
5175         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5176         0x0000ffff                                                              /* end                      */
5177     };
5178     DWORD shader_code_13_coissue[] =  {
5179         0xffff0103,                                                             /* ps_1_3                   */
5180         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5181         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5182         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5183         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5184         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5185         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5186         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5187         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5188         /* 0x40000000 = D3DSI_COISSUE */
5189         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5190         0x0000ffff                                                              /* end                      */
5191     };
5192     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5193      * compare against 0.5
5194      */
5195     DWORD shader_code_14_coissue[] =  {
5196         0xffff0104,                                                             /* ps_1_4                   */
5197         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5198         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5199         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5200         /* 0x40000000 = D3DSI_COISSUE */
5201         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5202         0x0000ffff                                                              /* end                      */
5203     };
5204     float quad1[] = {
5205         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5206          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5207         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5208          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5209     };
5210     float quad2[] = {
5211          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5212          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5213          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5214          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5215     };
5216     float quad3[] = {
5217          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5218          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5219          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5220          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5221     };
5222     float quad4[] = {
5223         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5224          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5225         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5226          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5227     };
5228     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5229     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5230     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5231     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5232
5233     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5234     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5235
5236     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5237     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5238     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5239     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5240     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5241     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5242     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5243     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5244     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5245     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5246     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5247     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5248     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5249     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5250     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5251     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5252
5253     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5254     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5255     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5256     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5257     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5258     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5259
5260     hr = IDirect3DDevice9_BeginScene(device);
5261     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5262     if(SUCCEEDED(hr))
5263     {
5264         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5265         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5266         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5267         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5268
5269         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5270         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5271         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5272         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5273
5274         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5275         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5276         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5277         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5278
5279         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5280         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5281         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5282         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5283
5284         hr = IDirect3DDevice9_EndScene(device);
5285         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5286     }
5287
5288     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5289     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5290
5291     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5292     color = getPixelColor(device, 158, 118);
5293     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5294     color = getPixelColor(device, 162, 118);
5295     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5296     color = getPixelColor(device, 158, 122);
5297     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5298     color = getPixelColor(device, 162, 122);
5299     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5300
5301     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5302     color = getPixelColor(device, 158, 358);
5303     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5304     color = getPixelColor(device, 162, 358);
5305     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5306         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5307     color = getPixelColor(device, 158, 362);
5308     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5309     color = getPixelColor(device, 162, 362);
5310     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5311         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5312
5313     /* 1.2 shader */
5314     color = getPixelColor(device, 478, 358);
5315     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5316     color = getPixelColor(device, 482, 358);
5317     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5318         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5319     color = getPixelColor(device, 478, 362);
5320     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5321     color = getPixelColor(device, 482, 362);
5322     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5323         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5324
5325     /* 1.3 shader */
5326     color = getPixelColor(device, 478, 118);
5327     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5328     color = getPixelColor(device, 482, 118);
5329     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5330         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5331     color = getPixelColor(device, 478, 122);
5332     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5333     color = getPixelColor(device, 482, 122);
5334     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5335         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5336
5337     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5338     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5339
5340     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5341     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5342     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5343     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5344     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5345     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5346
5347     hr = IDirect3DDevice9_BeginScene(device);
5348     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5349     if(SUCCEEDED(hr))
5350     {
5351         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5352         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5353         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5354         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5355
5356         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5357         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5358         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5359         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5360
5361         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5362         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5363         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5364         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5365
5366         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5367         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5368         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5369         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5370
5371         hr = IDirect3DDevice9_EndScene(device);
5372         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5373     }
5374
5375     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5376     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5377
5378     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5379      * that we swapped the values in c1 and c2 to make the other tests return some color
5380      */
5381     color = getPixelColor(device, 158, 118);
5382     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5383     color = getPixelColor(device, 162, 118);
5384     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5385     color = getPixelColor(device, 158, 122);
5386     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5387     color = getPixelColor(device, 162, 122);
5388     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5389
5390     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5391     color = getPixelColor(device, 158, 358);
5392     ok(color_match(color, 0x0000ff00, 1),
5393         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5394     color = getPixelColor(device, 162, 358);
5395     ok(color_match(color, 0x0000ff00, 1),
5396         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5397     color = getPixelColor(device, 158, 362);
5398     ok(color_match(color, 0x0000ff00, 1),
5399         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5400     color = getPixelColor(device, 162, 362);
5401     ok(color_match(color, 0x0000ff00, 1),
5402         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5403
5404     /* 1.2 shader */
5405     color = getPixelColor(device, 478, 358);
5406     ok(color_match(color, 0x0000ff00, 1),
5407         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5408     color = getPixelColor(device, 482, 358);
5409     ok(color_match(color, 0x0000ff00, 1),
5410         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5411     color = getPixelColor(device, 478, 362);
5412     ok(color_match(color, 0x0000ff00, 1),
5413         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5414     color = getPixelColor(device, 482, 362);
5415     ok(color_match(color, 0x0000ff00, 1),
5416         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5417
5418     /* 1.3 shader */
5419     color = getPixelColor(device, 478, 118);
5420     ok(color_match(color, 0x0000ff00, 1),
5421         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5422     color = getPixelColor(device, 482, 118);
5423     ok(color_match(color, 0x0000ff00, 1),
5424         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5425     color = getPixelColor(device, 478, 122);
5426     ok(color_match(color, 0x0000ff00, 1),
5427         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5428     color = getPixelColor(device, 482, 122);
5429     ok(color_match(color, 0x0000ff00, 1),
5430         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5431
5432     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5433     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5434
5435     IDirect3DPixelShader9_Release(shader_14_coissue);
5436     IDirect3DPixelShader9_Release(shader_13_coissue);
5437     IDirect3DPixelShader9_Release(shader_12_coissue);
5438     IDirect3DPixelShader9_Release(shader_11_coissue);
5439     IDirect3DPixelShader9_Release(shader_14);
5440     IDirect3DPixelShader9_Release(shader_13);
5441     IDirect3DPixelShader9_Release(shader_12);
5442     IDirect3DPixelShader9_Release(shader_11);
5443 }
5444
5445 static void nested_loop_test(IDirect3DDevice9 *device) {
5446     const DWORD shader_code[] = {
5447         0xffff0300,                                                             /* ps_3_0               */
5448         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5449         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5450         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5451         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5452         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5453         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5454         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5455         0x0000001d,                                                             /* endloop              */
5456         0x0000001d,                                                             /* endloop              */
5457         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5458         0x0000ffff                                                              /* end                  */
5459     };
5460     IDirect3DPixelShader9 *shader;
5461     HRESULT hr;
5462     DWORD color;
5463     const float quad[] = {
5464         -1.0,   -1.0,   0.1,
5465          1.0,   -1.0,   0.1,
5466         -1.0,    1.0,   0.1,
5467          1.0,    1.0,   0.1
5468     };
5469
5470     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5471     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5472     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5473     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5474     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5475     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5476     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5477     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5478
5479     hr = IDirect3DDevice9_BeginScene(device);
5480     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5481     if(SUCCEEDED(hr))
5482     {
5483         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5484         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5485         hr = IDirect3DDevice9_EndScene(device);
5486         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5487     }
5488
5489     color = getPixelColor(device, 360, 240);
5490     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5491        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5492
5493     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5494     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5495
5496     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5497     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5498     IDirect3DPixelShader9_Release(shader);
5499 }
5500
5501 struct varying_test_struct
5502 {
5503     const DWORD             *shader_code;
5504     IDirect3DPixelShader9   *shader;
5505     DWORD                   color, color_rhw;
5506     const char              *name;
5507     BOOL                    todo, todo_rhw;
5508 };
5509
5510 struct hugeVertex
5511 {
5512     float pos_x,        pos_y,      pos_z,      rhw;
5513     float weight_1,     weight_2,   weight_3,   weight_4;
5514     float index_1,      index_2,    index_3,    index_4;
5515     float normal_1,     normal_2,   normal_3,   normal_4;
5516     float fog_1,        fog_2,      fog_3,      fog_4;
5517     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5518     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5519     float binormal_1,   binormal_2, binormal_3, binormal_4;
5520     float depth_1,      depth_2,    depth_3,    depth_4;
5521     DWORD diffuse, specular;
5522 };
5523
5524 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5525     /* dcl_position: fails to compile */
5526     const DWORD blendweight_code[] = {
5527         0xffff0300,                             /* ps_3_0                   */
5528         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5529         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5530         0x0000ffff                              /* end                      */
5531     };
5532     const DWORD blendindices_code[] = {
5533         0xffff0300,                             /* ps_3_0                   */
5534         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5535         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5536         0x0000ffff                              /* end                      */
5537     };
5538     const DWORD normal_code[] = {
5539         0xffff0300,                             /* ps_3_0                   */
5540         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5541         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5542         0x0000ffff                              /* end                      */
5543     };
5544     /* psize: fails? */
5545     const DWORD texcoord0_code[] = {
5546         0xffff0300,                             /* ps_3_0                   */
5547         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5548         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5549         0x0000ffff                              /* end                      */
5550     };
5551     const DWORD tangent_code[] = {
5552         0xffff0300,                             /* ps_3_0                   */
5553         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5554         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5555         0x0000ffff                              /* end                      */
5556     };
5557     const DWORD binormal_code[] = {
5558         0xffff0300,                             /* ps_3_0                   */
5559         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5560         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5561         0x0000ffff                              /* end                      */
5562     };
5563     /* tessfactor: fails */
5564     /* positiont: fails */
5565     const DWORD color_code[] = {
5566         0xffff0300,                             /* ps_3_0                   */
5567         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5568         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5569         0x0000ffff                              /* end                      */
5570     };
5571     const DWORD fog_code[] = {
5572         0xffff0300,                             /* ps_3_0                   */
5573         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5574         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5575         0x0000ffff                              /* end                      */
5576     };
5577     const DWORD depth_code[] = {
5578         0xffff0300,                             /* ps_3_0                   */
5579         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5580         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5581         0x0000ffff                              /* end                      */
5582     };
5583     const DWORD specular_code[] = {
5584         0xffff0300,                             /* ps_3_0                   */
5585         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5586         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5587         0x0000ffff                              /* end                      */
5588     };
5589     /* sample: fails */
5590
5591     struct varying_test_struct tests[] = {
5592        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5593        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5594        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5595        /* Why does dx not forward the texcoord? */
5596        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5597        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5598        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5599        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5600        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5601        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5602        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5603     };
5604     /* Declare a monster vertex type :-) */
5605     static const D3DVERTEXELEMENT9 decl_elements[] = {
5606         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5607         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5608         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5609         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5610         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5611         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5612         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5613         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5614         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5615         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5616         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5617         D3DDECL_END()
5618     };
5619     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5620         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5621         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5622         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5623         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5624         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5625         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5626         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5627         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5628         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5629         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5630         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5631         D3DDECL_END()
5632     };
5633     struct hugeVertex data[4] = {
5634         {
5635             -1.0,   -1.0,   0.1,    1.0,
5636              0.1,    0.1,   0.1,    0.1,
5637              0.2,    0.2,   0.2,    0.2,
5638              0.3,    0.3,   0.3,    0.3,
5639              0.4,    0.4,   0.4,    0.4,
5640              0.50,   0.55,  0.55,   0.55,
5641              0.6,    0.6,   0.6,    0.7,
5642              0.7,    0.7,   0.7,    0.6,
5643              0.8,    0.8,   0.8,    0.8,
5644              0xe6e6e6e6, /* 0.9 * 256 */
5645              0x224488ff  /* Nothing special */
5646         },
5647         {
5648              1.0,   -1.0,   0.1,    1.0,
5649              0.1,    0.1,   0.1,    0.1,
5650              0.2,    0.2,   0.2,    0.2,
5651              0.3,    0.3,   0.3,    0.3,
5652              0.4,    0.4,   0.4,    0.4,
5653              0.50,   0.55,  0.55,   0.55,
5654              0.6,    0.6,   0.6,    0.7,
5655              0.7,    0.7,   0.7,    0.6,
5656              0.8,    0.8,   0.8,    0.8,
5657              0xe6e6e6e6, /* 0.9 * 256 */
5658              0x224488ff /* Nothing special */
5659         },
5660         {
5661             -1.0,    1.0,   0.1,    1.0,
5662              0.1,    0.1,   0.1,    0.1,
5663              0.2,    0.2,   0.2,    0.2,
5664              0.3,    0.3,   0.3,    0.3,
5665              0.4,    0.4,   0.4,    0.4,
5666              0.50,   0.55,  0.55,   0.55,
5667              0.6,    0.6,   0.6,    0.7,
5668              0.7,    0.7,   0.7,    0.6,
5669              0.8,    0.8,   0.8,    0.8,
5670              0xe6e6e6e6, /* 0.9 * 256 */
5671              0x224488ff /* Nothing special */
5672         },
5673         {
5674              1.0,    1.0,   0.1,    1.0,
5675              0.1,    0.1,   0.1,    0.1,
5676              0.2,    0.2,   0.2,    0.2,
5677              0.3,    0.3,   0.3,    0.3,
5678              0.4,    0.4,   0.4,    0.4,
5679              0.50,   0.55,  0.55,   0.55,
5680              0.6,    0.6,   0.6,    0.7,
5681              0.7,    0.7,   0.7,    0.6,
5682              0.8,    0.8,   0.8,    0.8,
5683              0xe6e6e6e6, /* 0.9 * 256 */
5684              0x224488ff /* Nothing special */
5685         },
5686     };
5687     struct hugeVertex data2[4];
5688     IDirect3DVertexDeclaration9 *decl;
5689     IDirect3DVertexDeclaration9 *decl2;
5690     HRESULT hr;
5691     unsigned int i;
5692     DWORD color, r, g, b, r_e, g_e, b_e;
5693     BOOL drawok;
5694
5695     memcpy(data2, data, sizeof(data2));
5696     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5697     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5698     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5699     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5700
5701     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5702     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5703     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5704     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5705     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5706     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5707
5708     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5709     {
5710         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5711         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5712            tests[i].name, hr);
5713     }
5714
5715     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5716     {
5717         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5718         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5719
5720         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5721         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5722
5723         hr = IDirect3DDevice9_BeginScene(device);
5724         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5725         drawok = FALSE;
5726         if(SUCCEEDED(hr))
5727         {
5728             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5729             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5730             drawok = SUCCEEDED(hr);
5731             hr = IDirect3DDevice9_EndScene(device);
5732             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5733         }
5734
5735         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5736          * the failure and do not check the color if it failed
5737          */
5738         if(!drawok) {
5739             continue;
5740         }
5741
5742         color = getPixelColor(device, 360, 240);
5743         r = color & 0x00ff0000 >> 16;
5744         g = color & 0x0000ff00 >>  8;
5745         b = color & 0x000000ff;
5746         r_e = tests[i].color & 0x00ff0000 >> 16;
5747         g_e = tests[i].color & 0x0000ff00 >>  8;
5748         b_e = tests[i].color & 0x000000ff;
5749
5750         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5751         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5752
5753         if(tests[i].todo) {
5754             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5755                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5756                          tests[i].name, color, tests[i].color);
5757         } else {
5758             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5759                "Test %s returned color 0x%08x, expected 0x%08x\n",
5760                tests[i].name, color, tests[i].color);
5761         }
5762     }
5763
5764     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5765     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5766     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5767     {
5768         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5769         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5770
5771         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5772         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5773
5774         hr = IDirect3DDevice9_BeginScene(device);
5775         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5776         if(SUCCEEDED(hr))
5777         {
5778             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5779             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780             hr = IDirect3DDevice9_EndScene(device);
5781             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5782         }
5783
5784         color = getPixelColor(device, 360, 240);
5785         r = color & 0x00ff0000 >> 16;
5786         g = color & 0x0000ff00 >>  8;
5787         b = color & 0x000000ff;
5788         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5789         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5790         b_e = tests[i].color_rhw & 0x000000ff;
5791
5792         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5793         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5794
5795         if(tests[i].todo_rhw) {
5796             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5797              * pipeline
5798              */
5799             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5800                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5801                          tests[i].name, color, tests[i].color_rhw);
5802         } else {
5803             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5804                "Test %s returned color 0x%08x, expected 0x%08x\n",
5805                tests[i].name, color, tests[i].color_rhw);
5806         }
5807     }
5808
5809     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5810     {
5811         IDirect3DPixelShader9_Release(tests[i].shader);
5812     }
5813
5814     IDirect3DVertexDeclaration9_Release(decl2);
5815     IDirect3DVertexDeclaration9_Release(decl);
5816 }
5817
5818 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5819     static const DWORD ps_code[] = {
5820     0xffff0300,                                                             /* ps_3_0                       */
5821     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5822     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5823     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5824     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5825     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5826     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5827     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5828     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5829     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5830
5831     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5832     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5833     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5834     0x0000001d,                                                             /* endloop                      */
5835     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5836     0x0000ffff                                                              /* end                          */
5837     };
5838     static const DWORD vs_1_code[] = {
5839     0xfffe0101,                                                             /* vs_1_1                       */
5840     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5841     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5842     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5843     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5844     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5845     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5846     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5847     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5848     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5849     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5850     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5851     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5852     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5853     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5854     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5855     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5856     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5857     0x0000ffff
5858     };
5859     DWORD vs_2_code[] = {
5860     0xfffe0200,                                                             /* vs_2_0                       */
5861     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5862     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5863     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5864     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5865     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5866     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5867     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5868     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5869     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5870     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5871     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5872     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5873     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5874     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5875     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5876     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5877     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5878     0x0000ffff                                                              /* end                          */
5879     };
5880     /* TODO: Define normal, tangent, blendweight and depth here */
5881     static const DWORD vs_3_code[] = {
5882     0xfffe0300,                                                             /* vs_3_0                       */
5883     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5884     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5885     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5886     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5887     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5888     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5889     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5890     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5891     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5892     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5893     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5894     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5895     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5896     0x0000ffff                                                              /* end                          */
5897     };
5898     float quad1[] =  {
5899         -1.0,   -1.0,   0.1,
5900          0.0,   -1.0,   0.1,
5901         -1.0,    0.0,   0.1,
5902          0.0,    0.0,   0.1
5903     };
5904     float quad2[] =  {
5905          0.0,   -1.0,   0.1,
5906          1.0,   -1.0,   0.1,
5907          0.0,    0.0,   0.1,
5908          1.0,    0.0,   0.1
5909     };
5910     float quad3[] =  {
5911         -1.0,    0.0,   0.1,
5912          0.0,    0.0,   0.1,
5913         -1.0,    1.0,   0.1,
5914          0.0,    1.0,   0.1
5915     };
5916
5917     HRESULT hr;
5918     DWORD color;
5919     IDirect3DPixelShader9 *pixelshader = NULL;
5920     IDirect3DVertexShader9 *vs_1_shader = NULL;
5921     IDirect3DVertexShader9 *vs_2_shader = NULL;
5922     IDirect3DVertexShader9 *vs_3_shader = NULL;
5923
5924     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5925     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5926
5927     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5928     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5929     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5930     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5931     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5932     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5933     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5934     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5935     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5936     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5937     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5938
5939     hr = IDirect3DDevice9_BeginScene(device);
5940     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5941     if(SUCCEEDED(hr))
5942     {
5943         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5944         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5945         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5946         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5947
5948         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5949         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5951         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5952
5953         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5954         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5955         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5956         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5957
5958         hr = IDirect3DDevice9_EndScene(device);
5959         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5960     }
5961
5962     color = getPixelColor(device, 160, 120);
5963     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5964        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5965     /* Accept two ways of oFog handling:
5966      *
5967      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5968      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5969      *
5970      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5971      *    This happens with software vertex processing and on Intel cards
5972      *
5973      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5974      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5975      */
5976     color = getPixelColor(device, 160, 360);
5977     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5978        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5979        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5980     color = getPixelColor(device, 480, 360);
5981     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5982        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5983        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5984
5985     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5986     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5987
5988     /* cleanup */
5989     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5990     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5991     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5992     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5993     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5994     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5995     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5996     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5997 }
5998
5999 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
6000     static const DWORD vs_code[] = {
6001     0xfffe0300,                                                             /* vs_3_0                       */
6002     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6003     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
6004     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
6005     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
6006     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
6007     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
6008     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
6009     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
6010     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
6011     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
6012     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
6013     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
6014     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
6015
6016     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
6017     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
6018     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
6019     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
6020     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
6021     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
6022     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
6023     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
6024     0x0000ffff                                                              /* end                          */
6025     };
6026     static const DWORD ps_1_code[] = {
6027     0xffff0104,                                                             /* ps_1_4                       */
6028     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6029     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
6030     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
6031     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
6032     0x0000ffff                                                              /* end                          */
6033     };
6034     static const DWORD ps_2_code[] = {
6035     0xffff0200,                                                             /* ps_2_0                       */
6036     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
6037     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
6038     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
6039
6040     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6041     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
6042     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6043     0x0000ffff                                                              /* end                          */
6044     };
6045     static const DWORD ps_3_code[] = {
6046     0xffff0300,                                                             /* ps_3_0                       */
6047     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
6048     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
6049     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
6050
6051     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
6052     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
6053     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
6054     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
6055     0x0000ffff                                                              /* end                          */
6056     };
6057
6058     float quad1[] =  {
6059         -1.0,   -1.0,   0.1,
6060          0.0,   -1.0,   0.1,
6061         -1.0,    0.0,   0.1,
6062          0.0,    0.0,   0.1
6063     };
6064     float quad2[] =  {
6065          0.0,   -1.0,   0.1,
6066          1.0,   -1.0,   0.1,
6067          0.0,    0.0,   0.1,
6068          1.0,    0.0,   0.1
6069     };
6070     float quad3[] =  {
6071         -1.0,    0.0,   0.1,
6072          0.0,    0.0,   0.1,
6073         -1.0,    1.0,   0.1,
6074          0.0,    1.0,   0.1
6075     };
6076     float quad4[] =  {
6077          0.0,    0.0,   0.1,
6078          1.0,    0.0,   0.1,
6079          0.0,    1.0,   0.1,
6080          1.0,    1.0,   0.1
6081     };
6082
6083     HRESULT hr;
6084     DWORD color;
6085     IDirect3DVertexShader9 *vertexshader = NULL;
6086     IDirect3DPixelShader9 *ps_1_shader = NULL;
6087     IDirect3DPixelShader9 *ps_2_shader = NULL;
6088     IDirect3DPixelShader9 *ps_3_shader = NULL;
6089     IDirect3DTexture9 *texture = NULL;
6090     D3DLOCKED_RECT lr;
6091     unsigned int x, y;
6092
6093     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6094     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6095
6096     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
6097     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
6098     if(FAILED(hr)) {
6099         skip("D3DFMT_A16B16G16R16 textures not supported\n");
6100         return;
6101     }
6102     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6103     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
6104     for(y = 0; y < 512; y++) {
6105         for(x = 0; x < 512; x++) {
6106             double r_f = (double) x / (double) 512;
6107             double g_f = (double) y / (double) 512;
6108             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
6109             unsigned short r = (unsigned short) (r_f * 65535.0);
6110             unsigned short g = (unsigned short) (g_f * 65535.0);
6111             dst[0] = r;
6112             dst[1] = g;
6113             dst[2] = 0;
6114             dst[3] = 65535;
6115         }
6116     }
6117     hr = IDirect3DTexture9_UnlockRect(texture, 0);
6118     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
6119
6120     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
6121     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6122     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
6123     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6124     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
6125     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6126     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
6127     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6128     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
6129     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6130     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6131
6132     hr = IDirect3DDevice9_BeginScene(device);
6133     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6134     if(SUCCEEDED(hr))
6135     {
6136         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
6137         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6138         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6139         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6140
6141         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
6142         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6143         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6144         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6145
6146         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
6147         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6148         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6149         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6150
6151         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6152         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6153         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6154         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6155         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6156         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6157         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
6158         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6159         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6160         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6161         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
6162         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
6163         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6164         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6165
6166         hr = IDirect3DDevice9_EndScene(device);
6167         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6168     }
6169
6170     color = getPixelColor(device, 160, 120);
6171     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
6172        (color & 0x0000ff00) == 0x0000ff00 &&
6173        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
6174        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
6175     color = getPixelColor(device, 160, 360);
6176     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6177        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
6178        (color & 0x000000ff) == 0x00000000,
6179        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
6180     color = getPixelColor(device, 480, 360);
6181     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6182        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6183        (color & 0x000000ff) == 0x00000000,
6184        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
6185     color = getPixelColor(device, 480, 160);
6186     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
6187        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
6188        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
6189        (color & 0x000000ff) == 0x00000000),
6190        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
6191
6192     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6193     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6194
6195     /* cleanup */
6196     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6197     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
6198     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6199     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6200     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6201     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6202     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
6203     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
6204     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
6205     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
6206     if(texture) IDirect3DTexture9_Release(texture);
6207 }
6208
6209 static void test_compare_instructions(IDirect3DDevice9 *device)
6210 {
6211     DWORD shader_sge_vec_code[] = {
6212         0xfffe0101,                                         /* vs_1_1                   */
6213         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6214         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6215         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6216         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
6217         0x0000ffff                                          /* end                      */
6218     };
6219     DWORD shader_slt_vec_code[] = {
6220         0xfffe0101,                                         /* vs_1_1                   */
6221         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6222         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6223         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6224         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
6225         0x0000ffff                                          /* end                      */
6226     };
6227     DWORD shader_sge_scalar_code[] = {
6228         0xfffe0101,                                         /* vs_1_1                   */
6229         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6230         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6231         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6232         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
6233         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
6234         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
6235         0x0000ffff                                          /* end                      */
6236     };
6237     DWORD shader_slt_scalar_code[] = {
6238         0xfffe0101,                                         /* vs_1_1                   */
6239         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
6240         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
6241         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
6242         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
6243         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
6244         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
6245         0x0000ffff                                          /* end                      */
6246     };
6247     IDirect3DVertexShader9 *shader_sge_vec;
6248     IDirect3DVertexShader9 *shader_slt_vec;
6249     IDirect3DVertexShader9 *shader_sge_scalar;
6250     IDirect3DVertexShader9 *shader_slt_scalar;
6251     HRESULT hr, color;
6252     float quad1[] =  {
6253         -1.0,   -1.0,   0.1,
6254          0.0,   -1.0,   0.1,
6255         -1.0,    0.0,   0.1,
6256          0.0,    0.0,   0.1
6257     };
6258     float quad2[] =  {
6259          0.0,   -1.0,   0.1,
6260          1.0,   -1.0,   0.1,
6261          0.0,    0.0,   0.1,
6262          1.0,    0.0,   0.1
6263     };
6264     float quad3[] =  {
6265         -1.0,    0.0,   0.1,
6266          0.0,    0.0,   0.1,
6267         -1.0,    1.0,   0.1,
6268          0.0,    1.0,   0.1
6269     };
6270     float quad4[] =  {
6271          0.0,    0.0,   0.1,
6272          1.0,    0.0,   0.1,
6273          0.0,    1.0,   0.1,
6274          1.0,    1.0,   0.1
6275     };
6276     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6277     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6278
6279     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6280     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6281
6282     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6283     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6285     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6287     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6288     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6289     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6290     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6291     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6292     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6293     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6294     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6295     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6296
6297     hr = IDirect3DDevice9_BeginScene(device);
6298     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6299     if(SUCCEEDED(hr))
6300     {
6301         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6302         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6303         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6304         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6305
6306         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6307         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6308         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6309         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6310
6311         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6312         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6313         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6314         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6315
6316         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6317         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6318
6319         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6320         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6321         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6322         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6323
6324         hr = IDirect3DDevice9_EndScene(device);
6325         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6326     }
6327
6328     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6329     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6330
6331     color = getPixelColor(device, 160, 360);
6332     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6333     color = getPixelColor(device, 480, 360);
6334     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6335     color = getPixelColor(device, 160, 120);
6336     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6337     color = getPixelColor(device, 480, 160);
6338     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6339
6340     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6341     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6342
6343     IDirect3DVertexShader9_Release(shader_sge_vec);
6344     IDirect3DVertexShader9_Release(shader_slt_vec);
6345     IDirect3DVertexShader9_Release(shader_sge_scalar);
6346     IDirect3DVertexShader9_Release(shader_slt_scalar);
6347 }
6348
6349 static void test_vshader_input(IDirect3DDevice9 *device)
6350 {
6351     DWORD swapped_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_texcoord0 v1     */
6357         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6358         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6359         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6360         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6361         0x0000ffff                                          /* end                  */
6362     };
6363     DWORD swapped_shader_code_1[] = {
6364         0xfffe0101,                                         /* vs_1_1               */
6365         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6366         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6367         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6368         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6369         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6370         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6371         0x0000ffff                                          /* end                  */
6372     };
6373     DWORD swapped_shader_code_2[] = {
6374         0xfffe0200,                                         /* vs_2_0               */
6375         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6376         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6377         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6378         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6379         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6380         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6381         0x0000ffff                                          /* end                  */
6382     };
6383     DWORD texcoord_color_shader_code_3[] = {
6384         0xfffe0300,                                         /* vs_3_0               */
6385         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6386         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6387         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6388         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6389         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6390         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6391         0x0000ffff                                          /* end                  */
6392     };
6393     DWORD texcoord_color_shader_code_2[] = {
6394         0xfffe0200,                                         /* vs_2_0               */
6395         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6396         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6397         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6398         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6399         0x0000ffff                                          /* end                  */
6400     };
6401     DWORD texcoord_color_shader_code_1[] = {
6402         0xfffe0101,                                         /* vs_1_1               */
6403         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6404         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6405         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6406         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6407         0x0000ffff                                          /* end                  */
6408     };
6409     DWORD color_color_shader_code_3[] = {
6410         0xfffe0300,                                         /* vs_3_0               */
6411         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6412         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6413         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6414         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6415         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6416         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6417         0x0000ffff                                          /* end                  */
6418     };
6419     DWORD color_color_shader_code_2[] = {
6420         0xfffe0200,                                         /* vs_2_0               */
6421         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6422         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6423         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6424         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6425         0x0000ffff                                          /* end                  */
6426     };
6427     DWORD color_color_shader_code_1[] = {
6428         0xfffe0101,                                         /* vs_1_1               */
6429         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6430         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6431         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6432         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6433         0x0000ffff                                          /* end                  */
6434     };
6435     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6436     HRESULT hr;
6437     DWORD color;
6438     float quad1[] =  {
6439         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6440          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6441         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6442          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6443     };
6444     float quad2[] =  {
6445          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6446          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6447          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6448          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6449     };
6450     float quad3[] =  {
6451         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6452          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6453         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6454          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6455     };
6456     float quad4[] =  {
6457          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6458          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6459          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6460          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6461     };
6462     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6463         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6464         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6465         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6466         D3DDECL_END()
6467     };
6468     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6469         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6470         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6471         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6472         D3DDECL_END()
6473     };
6474     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6475         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6476         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6477         D3DDECL_END()
6478     };
6479     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6480         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6481         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6482         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6483         D3DDECL_END()
6484     };
6485     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6486         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6487         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6488         D3DDECL_END()
6489     };
6490     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6491         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6492         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6493         D3DDECL_END()
6494     };
6495     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6496         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6497         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6498         D3DDECL_END()
6499     };
6500     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6501         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6502         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6503         D3DDECL_END()
6504     };
6505     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6506     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6507     unsigned int i;
6508     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6509     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6510
6511     struct vertex quad1_color[] =  {
6512        {-1.0,   -1.0,   0.1,    0x00ff8040},
6513        { 0.0,   -1.0,   0.1,    0x00ff8040},
6514        {-1.0,    0.0,   0.1,    0x00ff8040},
6515        { 0.0,    0.0,   0.1,    0x00ff8040}
6516     };
6517     struct vertex quad2_color[] =  {
6518        { 0.0,   -1.0,   0.1,    0x00ff8040},
6519        { 1.0,   -1.0,   0.1,    0x00ff8040},
6520        { 0.0,    0.0,   0.1,    0x00ff8040},
6521        { 1.0,    0.0,   0.1,    0x00ff8040}
6522     };
6523     struct vertex quad3_color[] =  {
6524        {-1.0,    0.0,   0.1,    0x00ff8040},
6525        { 0.0,    0.0,   0.1,    0x00ff8040},
6526        {-1.0,    1.0,   0.1,    0x00ff8040},
6527        { 0.0,    1.0,   0.1,    0x00ff8040}
6528     };
6529     float quad4_color[] =  {
6530          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6531          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6532          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6533          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6534     };
6535
6536     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6537     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6538     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6539     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6540     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6541     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6542     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6543     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6544
6545     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6546     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6547     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6548     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6549     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6550     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6551     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6552     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6553
6554     for(i = 1; i <= 3; i++) {
6555         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6556         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6557         if(i == 3) {
6558             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6559             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6560         } else if(i == 2){
6561             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6562             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6563         } else if(i == 1) {
6564             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6565             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6566         }
6567
6568         hr = IDirect3DDevice9_BeginScene(device);
6569         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6570         if(SUCCEEDED(hr))
6571         {
6572             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6573             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6574
6575             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6576             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6577             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6578             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6579
6580             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6581             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6582             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6583             if(i == 3 || i == 2) {
6584                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6585             } else if(i == 1) {
6586                 /* Succeeds or fails, depending on SW or HW vertex processing */
6587                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6588             }
6589
6590             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6591             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6592             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6593             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6594
6595             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6596             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6597             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6598             if(i == 3 || i == 2) {
6599                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6600             } else if(i == 1) {
6601                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6602             }
6603
6604             hr = IDirect3DDevice9_EndScene(device);
6605             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6606         }
6607
6608         if(i == 3 || i == 2) {
6609             color = getPixelColor(device, 160, 360);
6610             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6611                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6612
6613             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6614             color = getPixelColor(device, 480, 360);
6615             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6616                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6617             color = getPixelColor(device, 160, 120);
6618             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6619             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6620                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6621
6622             color = getPixelColor(device, 480, 160);
6623             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6624         } else if(i == 1) {
6625             color = getPixelColor(device, 160, 360);
6626             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6627                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6628             color = getPixelColor(device, 480, 360);
6629             /* Accept the clear color as well in this case, since SW VP returns an error */
6630             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6631             color = getPixelColor(device, 160, 120);
6632             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6633                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6634             color = getPixelColor(device, 480, 160);
6635             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6636         }
6637
6638         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6639         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6640
6641         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6642         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6643
6644         /* Now find out if the whole streams are re-read, or just the last active value for the
6645          * vertices is used.
6646          */
6647         hr = IDirect3DDevice9_BeginScene(device);
6648         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6649         if(SUCCEEDED(hr))
6650         {
6651             float quad1_modified[] =  {
6652                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6653                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6654                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6655                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6656             };
6657             float quad2_modified[] =  {
6658                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6659                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6660                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6661                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6662             };
6663
6664             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6665             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6666
6667             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6668             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6669             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6670             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6671
6672             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6673             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6674             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6675             if(i == 3 || i == 2) {
6676                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6677             } else if(i == 1) {
6678                 /* Succeeds or fails, depending on SW or HW vertex processing */
6679                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6680             }
6681
6682             hr = IDirect3DDevice9_EndScene(device);
6683             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6684         }
6685
6686         color = getPixelColor(device, 480, 350);
6687         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6688          * as well.
6689          *
6690          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6691          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6692          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6693          * refrast's result.
6694          *
6695          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6696          */
6697         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6698            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6699
6700         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6701         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6702
6703         IDirect3DDevice9_SetVertexShader(device, NULL);
6704         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6705
6706         IDirect3DVertexShader9_Release(swapped_shader);
6707     }
6708
6709     for(i = 1; i <= 3; i++) {
6710         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6711         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6712         if(i == 3) {
6713             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6714             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6715             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6716             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6717         } else if(i == 2){
6718             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6719             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6720             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6721             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6722         } else if(i == 1) {
6723             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6724             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6725             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6726             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6727         }
6728
6729         hr = IDirect3DDevice9_BeginScene(device);
6730         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6731         if(SUCCEEDED(hr))
6732         {
6733             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6734             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6735             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6736             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6737             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6738             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6739
6740             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6741             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6742
6743             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6744             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6745             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6746             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6747             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6748             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6749
6750             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6751             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6752             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6753             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6754             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6755             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6756
6757             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6758             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6759             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6760             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6761
6762             hr = IDirect3DDevice9_EndScene(device);
6763             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6764         }
6765         IDirect3DDevice9_SetVertexShader(device, NULL);
6766         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6767
6768         color = getPixelColor(device, 160, 360);
6769         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6770            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6771         color = getPixelColor(device, 480, 360);
6772         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6773            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6774         color = getPixelColor(device, 160, 120);
6775         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6776            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6777         color = getPixelColor(device, 480, 160);
6778         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6779            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6780
6781         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6782         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6783
6784         IDirect3DVertexShader9_Release(texcoord_color_shader);
6785         IDirect3DVertexShader9_Release(color_color_shader);
6786     }
6787
6788     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6789     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6790     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6791     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6792
6793     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6794     IDirect3DVertexDeclaration9_Release(decl_color_color);
6795     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6796     IDirect3DVertexDeclaration9_Release(decl_color_float);
6797 }
6798
6799 static void srgbtexture_test(IDirect3DDevice9 *device)
6800 {
6801     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6802      * texture stage state to render a quad using that texture.  The resulting
6803      * color components should be 0x36 (~ 0.21), per this formula:
6804      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6805      * This is true where srgb_color > 0.04045.
6806      */
6807     IDirect3D9 *d3d = NULL;
6808     HRESULT hr;
6809     LPDIRECT3DTEXTURE9 texture = NULL;
6810     LPDIRECT3DSURFACE9 surface = NULL;
6811     D3DLOCKED_RECT lr;
6812     DWORD color;
6813     float quad[] = {
6814         -1.0,       1.0,       0.0,     0.0,    0.0,
6815          1.0,       1.0,       0.0,     1.0,    0.0,
6816         -1.0,      -1.0,       0.0,     0.0,    1.0,
6817          1.0,      -1.0,       0.0,     1.0,    1.0,
6818     };
6819
6820
6821     memset(&lr, 0, sizeof(lr));
6822     IDirect3DDevice9_GetDirect3D(device, &d3d);
6823     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6824                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6825                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6826         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6827         goto out;
6828     }
6829
6830     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6831                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6832                                         &texture, NULL);
6833     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6834     if(!texture) {
6835         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6836         goto out;
6837     }
6838     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6839     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6840
6841     fill_surface(surface, 0xff7f7f7f);
6842     IDirect3DSurface9_Release(surface);
6843
6844     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6845     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6846     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6847     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6848
6849     hr = IDirect3DDevice9_BeginScene(device);
6850     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6851     if(SUCCEEDED(hr))
6852     {
6853         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6854         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6855
6856         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6857         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6858
6859
6860         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6861         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6862
6863         hr = IDirect3DDevice9_EndScene(device);
6864         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6865     }
6866
6867     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6868     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6869     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6870     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6871
6872     color = getPixelColor(device, 320, 240);
6873     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6874
6875     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6876     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6877
6878 out:
6879     if(texture) IDirect3DTexture9_Release(texture);
6880     IDirect3D9_Release(d3d);
6881 }
6882
6883 static void shademode_test(IDirect3DDevice9 *device)
6884 {
6885     /* Render a quad and try all of the different fixed function shading models. */
6886     HRESULT hr;
6887     DWORD color0, color1;
6888     DWORD color0_gouraud = 0, color1_gouraud = 0;
6889     DWORD shademode = D3DSHADE_FLAT;
6890     DWORD primtype = D3DPT_TRIANGLESTRIP;
6891     LPVOID data = NULL;
6892     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6893     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6894     UINT i, j;
6895     struct vertex quad_strip[] =
6896     {
6897         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6898         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6899         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6900         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6901     };
6902     struct vertex quad_list[] =
6903     {
6904         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6905         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6906         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6907
6908         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6909         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6910         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6911     };
6912
6913     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6914                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6915     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6916     if (FAILED(hr)) goto bail;
6917
6918     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6919                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6920     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6921     if (FAILED(hr)) goto bail;
6922
6923     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6924     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6925
6926     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6927     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6928
6929     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6930     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6931     memcpy(data, quad_strip, sizeof(quad_strip));
6932     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6933     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6934
6935     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6936     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6937     memcpy(data, quad_list, sizeof(quad_list));
6938     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6939     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6940
6941     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6942      * the color fixups we have to do for FLAT shading will be dependent on that. */
6943     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6944     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6945
6946     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6947     for (j=0; j<2; j++) {
6948
6949         /* Inner loop just changes the D3DRS_SHADEMODE */
6950         for (i=0; i<3; i++) {
6951             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6952             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6953
6954             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6955             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6956
6957             hr = IDirect3DDevice9_BeginScene(device);
6958             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6959             if(SUCCEEDED(hr))
6960             {
6961                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6962                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6963
6964                 hr = IDirect3DDevice9_EndScene(device);
6965                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6966             }
6967
6968             /* Sample two spots from the output */
6969             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6970             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6971             switch(shademode) {
6972                 case D3DSHADE_FLAT:
6973                     /* Should take the color of the first vertex of each triangle */
6974                     if (0)
6975                     {
6976                         /* This test depends on EXT_provoking_vertex being
6977                          * available. This extension is currently (20090810)
6978                          * not common enough to let the test fail if it isn't
6979                          * present. */
6980                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6981                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6982                     }
6983                     shademode = D3DSHADE_GOURAUD;
6984                     break;
6985                 case D3DSHADE_GOURAUD:
6986                     /* Should be an interpolated blend */
6987
6988                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6989                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6990                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6991                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6992
6993                     color0_gouraud = color0;
6994                     color1_gouraud = color1;
6995
6996                     shademode = D3DSHADE_PHONG;
6997                     break;
6998                 case D3DSHADE_PHONG:
6999                     /* Should be the same as GOURAUD, since no hardware implements this */
7000                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
7001                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
7002                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
7003                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
7004
7005                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7006                             color0_gouraud, color0);
7007                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
7008                             color1_gouraud, color1);
7009                     break;
7010             }
7011         }
7012
7013         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7014         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7015
7016         /* Now, do it all over again with a TRIANGLELIST */
7017         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
7018         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7019         primtype = D3DPT_TRIANGLELIST;
7020         shademode = D3DSHADE_FLAT;
7021     }
7022
7023 bail:
7024     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7025     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7026     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
7027     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7028
7029     if (vb_strip)
7030         IDirect3DVertexBuffer9_Release(vb_strip);
7031     if (vb_list)
7032         IDirect3DVertexBuffer9_Release(vb_list);
7033 }
7034
7035
7036 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
7037 {
7038     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
7039      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
7040      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
7041      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
7042      * 0.73
7043      *
7044      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
7045      * so use shaders for this task
7046      */
7047     IDirect3DPixelShader9 *pshader;
7048     IDirect3DVertexShader9 *vshader;
7049     IDirect3D9 *d3d;
7050     DWORD vshader_code[] = {
7051         0xfffe0101,                                                             /* vs_1_1                       */
7052         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
7053         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
7054         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
7055         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
7056         0x0000ffff                                                              /* end                          */
7057     };
7058     DWORD pshader_code[] = {
7059         0xffff0101,                                                             /* ps_1_1                       */
7060         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
7061         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
7062         0x0000ffff                                                              /* end                          */
7063     };
7064     const float quad[] = {
7065        -1.0,   -1.0,    0.1,
7066         1.0,   -1.0,    0.1,
7067        -1.0,    1.0,    0.1,
7068         1.0,    1.0,    0.1
7069     };
7070     HRESULT hr;
7071     D3DCOLOR color;
7072
7073     IDirect3DDevice9_GetDirect3D(device, &d3d);
7074     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
7075      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
7076      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
7077      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
7078      * works
7079      */
7080     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
7081                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
7082                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
7083         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
7084         IDirect3D9_Release(d3d);
7085         return;
7086     }
7087     IDirect3D9_Release(d3d);
7088
7089     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
7090     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7091
7092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
7093     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7094     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
7095     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7096     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
7097     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7098     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
7099     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7100     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
7101     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7102
7103     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7104     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7105     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
7106     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7107     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7108     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
7109     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7110     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7111     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
7112     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7113
7114     hr = IDirect3DDevice9_BeginScene(device);
7115     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
7116     if(SUCCEEDED(hr)) {
7117         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
7118         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7119
7120         hr = IDirect3DDevice9_EndScene(device);
7121         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
7122     }
7123
7124     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7125     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
7126     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7127     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7128     IDirect3DPixelShader9_Release(pshader);
7129     IDirect3DVertexShader9_Release(vshader);
7130
7131     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
7132     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7133     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
7134     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7135
7136     color = getPixelColor(device, 160, 360);
7137     ok(color_match(color, 0x00808080, 1),
7138             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
7139     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7140     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7141 }
7142
7143 static void alpha_test(IDirect3DDevice9 *device)
7144 {
7145     HRESULT hr;
7146     IDirect3DTexture9 *offscreenTexture;
7147     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
7148     DWORD color;
7149
7150     struct vertex quad1[] =
7151     {
7152         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
7153         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
7154         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
7155         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
7156     };
7157     struct vertex quad2[] =
7158     {
7159         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
7160         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
7161         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
7162         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
7163     };
7164     static const float composite_quad[][5] = {
7165         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
7166         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
7167         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
7168         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
7169     };
7170
7171     /* Clear the render target with alpha = 0.5 */
7172     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7173     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7174
7175     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
7176     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
7177
7178     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7179     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7180     if(!backbuffer) {
7181         goto out;
7182     }
7183
7184     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
7185     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
7186     if(!offscreen) {
7187         goto out;
7188     }
7189
7190     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7191     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7192
7193     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7194     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7195     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7196     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
7197     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
7198     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
7199     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
7200     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
7201     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7202     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
7203
7204     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
7205     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7206     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
7207
7208         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
7209         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7210         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7211         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7212         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7213         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7214         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7215
7216         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7217         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7218         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7219         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7220         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7221         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7222
7223         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
7224          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
7225          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
7226         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
7227         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7228         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
7229         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7230
7231         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
7232         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7233         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
7234         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7235         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7236         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7237
7238         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
7239         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7240         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
7241         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7242         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7243         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7244
7245         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7246         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7247
7248         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7249          * Disable alpha blending for the final composition
7250          */
7251         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7252         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7253         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7254         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7255
7256         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7257         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7258         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7259         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7260         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7261         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7262
7263         hr = IDirect3DDevice9_EndScene(device);
7264         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7265     }
7266
7267     color = getPixelColor(device, 160, 360);
7268     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7269        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7270
7271     color = getPixelColor(device, 160, 120);
7272     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7273        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7274
7275     color = getPixelColor(device, 480, 360);
7276     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7277        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7278
7279     color = getPixelColor(device, 480, 120);
7280     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7281        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7282
7283     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7284
7285     out:
7286     /* restore things */
7287     if(backbuffer) {
7288         IDirect3DSurface9_Release(backbuffer);
7289     }
7290     if(offscreenTexture) {
7291         IDirect3DTexture9_Release(offscreenTexture);
7292     }
7293     if(offscreen) {
7294         IDirect3DSurface9_Release(offscreen);
7295     }
7296 }
7297
7298 struct vertex_shortcolor {
7299     float x, y, z;
7300     unsigned short r, g, b, a;
7301 };
7302 struct vertex_floatcolor {
7303     float x, y, z;
7304     float r, g, b, a;
7305 };
7306
7307 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7308 {
7309     HRESULT hr;
7310     BOOL s_ok, ub_ok, f_ok;
7311     DWORD color, size, i;
7312     void *data;
7313     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7314         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7315         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7316         D3DDECL_END()
7317     };
7318     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7319         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7320         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7321         D3DDECL_END()
7322     };
7323     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7324         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7325         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7326         D3DDECL_END()
7327     };
7328     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7329         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7330         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7331         D3DDECL_END()
7332     };
7333     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7334         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7335         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7336         D3DDECL_END()
7337     };
7338     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7339         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7340         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7341         D3DDECL_END()
7342     };
7343     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7344         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7345         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7346         D3DDECL_END()
7347     };
7348     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7349     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7350     IDirect3DVertexBuffer9 *vb, *vb2;
7351     struct vertex quad1[] =                             /* D3DCOLOR */
7352     {
7353         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7354         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7355         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7356         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7357     };
7358     struct vertex quad2[] =                             /* UBYTE4N */
7359     {
7360         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7361         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7362         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7363         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7364     };
7365     struct vertex_shortcolor quad3[] =                  /* short */
7366     {
7367         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7368         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7369         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7370         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7371     };
7372     struct vertex_floatcolor quad4[] =
7373     {
7374         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7375         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7376         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7377         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7378     };
7379     DWORD colors[] = {
7380         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7381         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7382         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7383         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7384         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7385         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7386         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7387         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7388         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7389         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7390         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7391         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7392         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7393         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7394         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7395         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7396     };
7397     float quads[] = {
7398         -1.0,   -1.0,     0.1,
7399         -1.0,    0.0,     0.1,
7400          0.0,   -1.0,     0.1,
7401          0.0,    0.0,     0.1,
7402
7403          0.0,   -1.0,     0.1,
7404          0.0,    0.0,     0.1,
7405          1.0,   -1.0,     0.1,
7406          1.0,    0.0,     0.1,
7407
7408          0.0,    0.0,     0.1,
7409          0.0,    1.0,     0.1,
7410          1.0,    0.0,     0.1,
7411          1.0,    1.0,     0.1,
7412
7413         -1.0,    0.0,     0.1,
7414         -1.0,    1.0,     0.1,
7415          0.0,    0.0,     0.1,
7416          0.0,    1.0,     0.1
7417     };
7418     struct tvertex quad_transformed[] = {
7419        {  90,    110,     0.1,      2.0,        0x00ffff00},
7420        { 570,    110,     0.1,      2.0,        0x00ffff00},
7421        {  90,    300,     0.1,      2.0,        0x00ffff00},
7422        { 570,    300,     0.1,      2.0,        0x00ffff00}
7423     };
7424     D3DCAPS9 caps;
7425
7426     memset(&caps, 0, sizeof(caps));
7427     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7428     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7429
7430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7431     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7432
7433     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7434     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7435     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7436     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7437     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7438     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7439     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7440         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7441         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7442         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7443         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7444     } else {
7445         trace("D3DDTCAPS_UBYTE4N not supported\n");
7446         dcl_ubyte_2 = NULL;
7447         dcl_ubyte = NULL;
7448     }
7449     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7450     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7451     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7452     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7453
7454     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7455     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7456                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7457     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7458
7459     hr = IDirect3DDevice9_BeginScene(device);
7460     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7461     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7462     if(SUCCEEDED(hr)) {
7463         if(dcl_color) {
7464             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7465             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7466             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7467             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7468         }
7469
7470         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7471          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7472          * using software vertex processing. Doh!
7473          */
7474         if(dcl_ubyte) {
7475             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7476             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7477             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7478             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7479             ub_ok = SUCCEEDED(hr);
7480         }
7481
7482         if(dcl_short) {
7483             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7484             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7485             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7486             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7487             s_ok = SUCCEEDED(hr);
7488         }
7489
7490         if(dcl_float) {
7491             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7492             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7493             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7494             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7495             f_ok = SUCCEEDED(hr);
7496         }
7497
7498         hr = IDirect3DDevice9_EndScene(device);
7499         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7500     }
7501
7502     if(dcl_short) {
7503         color = getPixelColor(device, 480, 360);
7504         ok(color == 0x000000ff || !s_ok,
7505            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7506     }
7507     if(dcl_ubyte) {
7508         color = getPixelColor(device, 160, 120);
7509         ok(color == 0x0000ffff || !ub_ok,
7510            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7511     }
7512     if(dcl_color) {
7513         color = getPixelColor(device, 160, 360);
7514         ok(color == 0x00ffff00,
7515            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7516     }
7517     if(dcl_float) {
7518         color = getPixelColor(device, 480, 120);
7519         ok(color == 0x00ff0000 || !f_ok,
7520            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7521     }
7522     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7523
7524     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7525      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7526      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7527      * whether the immediate mode code works
7528      */
7529     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7530     hr = IDirect3DDevice9_BeginScene(device);
7531     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7532     if(SUCCEEDED(hr)) {
7533         if(dcl_color) {
7534             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7535             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7536             memcpy(data, quad1, sizeof(quad1));
7537             hr = IDirect3DVertexBuffer9_Unlock(vb);
7538             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7539             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7540             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7541             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7542             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7543             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7544             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7545         }
7546
7547         if(dcl_ubyte) {
7548             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7549             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7550             memcpy(data, quad2, sizeof(quad2));
7551             hr = IDirect3DVertexBuffer9_Unlock(vb);
7552             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7553             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7554             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7555             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[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             ub_ok = SUCCEEDED(hr);
7561         }
7562
7563         if(dcl_short) {
7564             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7565             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7566             memcpy(data, quad3, sizeof(quad3));
7567             hr = IDirect3DVertexBuffer9_Unlock(vb);
7568             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7569             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7570             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7571             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7572             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7573             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7574             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7575                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7576             s_ok = SUCCEEDED(hr);
7577         }
7578
7579         if(dcl_float) {
7580             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7581             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7582             memcpy(data, quad4, sizeof(quad4));
7583             hr = IDirect3DVertexBuffer9_Unlock(vb);
7584             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7585             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7586             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7587             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7588             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7589             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7590             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7591                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7592             f_ok = SUCCEEDED(hr);
7593         }
7594
7595         hr = IDirect3DDevice9_EndScene(device);
7596         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7597     }
7598
7599     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7600     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7601     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7602     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7603
7604     if(dcl_short) {
7605         color = getPixelColor(device, 480, 360);
7606         ok(color == 0x000000ff || !s_ok,
7607            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7608     }
7609     if(dcl_ubyte) {
7610         color = getPixelColor(device, 160, 120);
7611         ok(color == 0x0000ffff || !ub_ok,
7612            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7613     }
7614     if(dcl_color) {
7615         color = getPixelColor(device, 160, 360);
7616         ok(color == 0x00ffff00,
7617            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7618     }
7619     if(dcl_float) {
7620         color = getPixelColor(device, 480, 120);
7621         ok(color == 0x00ff0000 || !f_ok,
7622            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7623     }
7624     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7625
7626     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7627     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7628
7629     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7630     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7631     memcpy(data, quad_transformed, sizeof(quad_transformed));
7632     hr = IDirect3DVertexBuffer9_Unlock(vb);
7633     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7634
7635     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7636     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7637
7638     hr = IDirect3DDevice9_BeginScene(device);
7639     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7640     if(SUCCEEDED(hr)) {
7641         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7642         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7643         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7644         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7645
7646         hr = IDirect3DDevice9_EndScene(device);
7647         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7648     }
7649
7650     color = getPixelColor(device, 88, 108);
7651     ok(color == 0x000000ff,
7652        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7653     color = getPixelColor(device, 92, 108);
7654     ok(color == 0x000000ff,
7655        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7656     color = getPixelColor(device, 88, 112);
7657     ok(color == 0x000000ff,
7658        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7659     color = getPixelColor(device, 92, 112);
7660     ok(color == 0x00ffff00,
7661        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7662
7663     color = getPixelColor(device, 568, 108);
7664     ok(color == 0x000000ff,
7665        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7666     color = getPixelColor(device, 572, 108);
7667     ok(color == 0x000000ff,
7668        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7669     color = getPixelColor(device, 568, 112);
7670     ok(color == 0x00ffff00,
7671        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7672     color = getPixelColor(device, 572, 112);
7673     ok(color == 0x000000ff,
7674        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7675
7676     color = getPixelColor(device, 88, 298);
7677     ok(color == 0x000000ff,
7678        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7679     color = getPixelColor(device, 92, 298);
7680     ok(color == 0x00ffff00,
7681        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7682     color = getPixelColor(device, 88, 302);
7683     ok(color == 0x000000ff,
7684        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7685     color = getPixelColor(device, 92, 302);
7686     ok(color == 0x000000ff,
7687        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7688
7689     color = getPixelColor(device, 568, 298);
7690     ok(color == 0x00ffff00,
7691        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7692     color = getPixelColor(device, 572, 298);
7693     ok(color == 0x000000ff,
7694        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7695     color = getPixelColor(device, 568, 302);
7696     ok(color == 0x000000ff,
7697        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7698     color = getPixelColor(device, 572, 302);
7699     ok(color == 0x000000ff,
7700        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7701
7702     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7703
7704     /* This test is pointless without those two declarations: */
7705     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7706         skip("color-ubyte switching test declarations aren't supported\n");
7707         goto out;
7708     }
7709
7710     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7711     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7712     memcpy(data, quads, sizeof(quads));
7713     hr = IDirect3DVertexBuffer9_Unlock(vb);
7714     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7715     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7716                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7717     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7718     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7719     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7720     memcpy(data, colors, sizeof(colors));
7721     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7722     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7723
7724     for(i = 0; i < 2; i++) {
7725         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7726         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7727
7728         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7729         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7730         if(i == 0) {
7731             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7732         } else {
7733             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7734         }
7735         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7736
7737         hr = IDirect3DDevice9_BeginScene(device);
7738         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7739         ub_ok = FALSE;
7740         if(SUCCEEDED(hr)) {
7741             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7742             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7743             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7744             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7745                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7746             ub_ok = SUCCEEDED(hr);
7747
7748             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7749             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7750             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7751             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7752
7753             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7754             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7755             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7756             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7757                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7758             ub_ok = (SUCCEEDED(hr) && ub_ok);
7759
7760             hr = IDirect3DDevice9_EndScene(device);
7761             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7762         }
7763
7764         if(i == 0) {
7765             color = getPixelColor(device, 480, 360);
7766             ok(color == 0x00ff0000,
7767                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7768             color = getPixelColor(device, 160, 120);
7769             ok(color == 0x00ffffff,
7770                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7771             color = getPixelColor(device, 160, 360);
7772             ok(color == 0x000000ff || !ub_ok,
7773                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7774             color = getPixelColor(device, 480, 120);
7775             ok(color == 0x000000ff || !ub_ok,
7776                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7777         } else {
7778             color = getPixelColor(device, 480, 360);
7779             ok(color == 0x000000ff,
7780                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7781             color = getPixelColor(device, 160, 120);
7782             ok(color == 0x00ffffff,
7783                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7784             color = getPixelColor(device, 160, 360);
7785             ok(color == 0x00ff0000 || !ub_ok,
7786                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7787             color = getPixelColor(device, 480, 120);
7788             ok(color == 0x00ff0000 || !ub_ok,
7789                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7790         }
7791         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7792     }
7793
7794     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7795     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7796     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7797     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7798     IDirect3DVertexBuffer9_Release(vb2);
7799
7800     out:
7801     IDirect3DVertexBuffer9_Release(vb);
7802     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7803     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7804     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7805     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7806     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7807     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7808     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7809 }
7810
7811 struct vertex_float16color {
7812     float x, y, z;
7813     DWORD c1, c2;
7814 };
7815
7816 static void test_vshader_float16(IDirect3DDevice9 *device)
7817 {
7818     HRESULT hr;
7819     DWORD color;
7820     void *data;
7821     static const D3DVERTEXELEMENT9 decl_elements[] = {
7822         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7823         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7824         D3DDECL_END()
7825     };
7826     IDirect3DVertexDeclaration9 *vdecl = NULL;
7827     IDirect3DVertexBuffer9 *buffer = NULL;
7828     IDirect3DVertexShader9 *shader;
7829     DWORD shader_code[] = {
7830         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7831         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7832         0x90e40001, 0x0000ffff
7833     };
7834     struct vertex_float16color quad[] = {
7835         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7836         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7837         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7838         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7839
7840         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7841         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7842         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7843         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7844
7845         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7846         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7847         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7848         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7849
7850         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7851         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7852         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7853         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7854     };
7855
7856     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7857     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7858
7859     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7860     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7861     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7862     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7863     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7864     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7865
7866     hr = IDirect3DDevice9_BeginScene(device);
7867     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7868     if(SUCCEEDED(hr)) {
7869         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7870         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7872         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7873         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7874         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7875         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7876         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7877         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7878         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7879
7880         hr = IDirect3DDevice9_EndScene(device);
7881         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7882     }
7883     color = getPixelColor(device, 480, 360);
7884     ok(color == 0x00ff0000,
7885        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7886     color = getPixelColor(device, 160, 120);
7887     ok(color == 0x00000000,
7888        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7889     color = getPixelColor(device, 160, 360);
7890     ok(color == 0x0000ff00,
7891        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7892     color = getPixelColor(device, 480, 120);
7893     ok(color == 0x000000ff,
7894        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7895     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7896
7897     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7898     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7899
7900     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7901                                              D3DPOOL_MANAGED, &buffer, NULL);
7902     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7903     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7904     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7905     memcpy(data, quad, sizeof(quad));
7906     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7907     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7908     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7909     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7910
7911     hr = IDirect3DDevice9_BeginScene(device);
7912     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7913     if(SUCCEEDED(hr)) {
7914             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7915             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7916             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7917             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7918             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7919             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7920             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7921             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7922
7923             hr = IDirect3DDevice9_EndScene(device);
7924             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7925     }
7926
7927     color = getPixelColor(device, 480, 360);
7928     ok(color == 0x00ff0000,
7929        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7930     color = getPixelColor(device, 160, 120);
7931     ok(color == 0x00000000,
7932        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7933     color = getPixelColor(device, 160, 360);
7934     ok(color == 0x0000ff00,
7935        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7936     color = getPixelColor(device, 480, 120);
7937     ok(color == 0x000000ff,
7938        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7939     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7940
7941     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7942     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7943     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7944     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7945     IDirect3DDevice9_SetVertexShader(device, NULL);
7946     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7947
7948     IDirect3DVertexDeclaration9_Release(vdecl);
7949     IDirect3DVertexShader9_Release(shader);
7950     IDirect3DVertexBuffer9_Release(buffer);
7951 }
7952
7953 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7954 {
7955     D3DCAPS9 caps;
7956     IDirect3DTexture9 *texture;
7957     HRESULT hr;
7958     D3DLOCKED_RECT rect;
7959     unsigned int x, y;
7960     DWORD *dst, color;
7961     const float quad[] = {
7962         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7963          1.0,   -1.0,   0.1,    1.2,   -0.2,
7964         -1.0,    1.0,   0.1,   -0.2,    1.2,
7965          1.0,    1.0,   0.1,    1.2,    1.2
7966     };
7967     memset(&caps, 0, sizeof(caps));
7968
7969     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7970     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7971     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7972         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7973         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7974            "Card has conditional NP2 support without power of two restriction set\n");
7975         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7976         return;
7977     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7978         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7979         return;
7980     }
7981
7982     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7983     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7984
7985     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7986     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7987
7988     memset(&rect, 0, sizeof(rect));
7989     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7990     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7991     for(y = 0; y < 10; y++) {
7992         for(x = 0; x < 10; x++) {
7993             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7994             if(x == 0 || x == 9 || y == 0 || y == 9) {
7995                 *dst = 0x00ff0000;
7996             } else {
7997                 *dst = 0x000000ff;
7998             }
7999         }
8000     }
8001     hr = IDirect3DTexture9_UnlockRect(texture, 0);
8002     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8003
8004     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8005     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8006     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
8007     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8008     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
8009     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
8010     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8011     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
8012
8013     hr = IDirect3DDevice9_BeginScene(device);
8014     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8015     if(SUCCEEDED(hr)) {
8016         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8017         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8018
8019         hr = IDirect3DDevice9_EndScene(device);
8020         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8021     }
8022
8023     color = getPixelColor(device,    1,  1);
8024     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
8025     color = getPixelColor(device, 639, 479);
8026     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
8027
8028     color = getPixelColor(device, 135, 101);
8029     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
8030     color = getPixelColor(device, 140, 101);
8031     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
8032     color = getPixelColor(device, 135, 105);
8033     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
8034     color = getPixelColor(device, 140, 105);
8035     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
8036
8037     color = getPixelColor(device, 135, 376);
8038     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
8039     color = getPixelColor(device, 140, 376);
8040     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
8041     color = getPixelColor(device, 135, 379);
8042     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
8043     color = getPixelColor(device, 140, 379);
8044     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
8045
8046     color = getPixelColor(device, 500, 101);
8047     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
8048     color = getPixelColor(device, 504, 101);
8049     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
8050     color = getPixelColor(device, 500, 105);
8051     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
8052     color = getPixelColor(device, 504, 105);
8053     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
8054
8055     color = getPixelColor(device, 500, 376);
8056     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
8057     color = getPixelColor(device, 504, 376);
8058     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
8059     color = getPixelColor(device, 500, 380);
8060     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
8061     color = getPixelColor(device, 504, 380);
8062     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
8063
8064     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8065
8066     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8067     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8068     IDirect3DTexture9_Release(texture);
8069 }
8070
8071 static void vFace_register_test(IDirect3DDevice9 *device)
8072 {
8073     HRESULT hr;
8074     DWORD color;
8075     const DWORD shader_code[] = {
8076         0xffff0300,                                                             /* ps_3_0                     */
8077         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8078         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
8079         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
8080         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
8081         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
8082         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8083         0x0000ffff                                                              /* END                        */
8084     };
8085     IDirect3DPixelShader9 *shader;
8086     IDirect3DTexture9 *texture;
8087     IDirect3DSurface9 *surface, *backbuffer;
8088     const float quad[] = {
8089         -1.0,   -1.0,   0.1,
8090          1.0,   -1.0,   0.1,
8091         -1.0,    0.0,   0.1,
8092
8093          1.0,   -1.0,   0.1,
8094          1.0,    0.0,   0.1,
8095         -1.0,    0.0,   0.1,
8096
8097         -1.0,    0.0,   0.1,
8098         -1.0,    1.0,   0.1,
8099          1.0,    0.0,   0.1,
8100
8101          1.0,    0.0,   0.1,
8102         -1.0,    1.0,   0.1,
8103          1.0,    1.0,   0.1,
8104     };
8105     const float blit[] = {
8106          0.0,   -1.0,   0.1,    0.0,    0.0,
8107          1.0,   -1.0,   0.1,    1.0,    0.0,
8108          0.0,    1.0,   0.1,    0.0,    1.0,
8109          1.0,    1.0,   0.1,    1.0,    1.0,
8110     };
8111
8112     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8113     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8114     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
8115     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8116     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8117     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
8118     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8119     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8120     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8121     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8122     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8123     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8124
8125     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8126     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8127
8128     hr = IDirect3DDevice9_BeginScene(device);
8129     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8130     if(SUCCEEDED(hr)) {
8131         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
8132         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8133         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8134         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8135         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8136         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8137         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8138         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8139         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
8141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8142
8143         /* Blit the texture onto the back buffer to make it visible */
8144         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8145         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8146         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8147         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8148         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8149         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8150         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8151         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
8152         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8153         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8154
8155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
8156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8157
8158         hr = IDirect3DDevice9_EndScene(device);
8159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8160     }
8161
8162     color = getPixelColor(device, 160, 360);
8163     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8164     color = getPixelColor(device, 160, 120);
8165     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8166     color = getPixelColor(device, 480, 360);
8167     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
8168     color = getPixelColor(device, 480, 120);
8169     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
8170     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8171
8172     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8173     IDirect3DDevice9_SetTexture(device, 0, NULL);
8174     IDirect3DPixelShader9_Release(shader);
8175     IDirect3DSurface9_Release(surface);
8176     IDirect3DSurface9_Release(backbuffer);
8177     IDirect3DTexture9_Release(texture);
8178 }
8179
8180 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
8181 {
8182     HRESULT hr;
8183     DWORD color;
8184     int i;
8185     D3DCAPS9 caps;
8186     BOOL L6V5U5_supported = FALSE;
8187     IDirect3DTexture9 *tex1, *tex2;
8188     D3DLOCKED_RECT locked_rect;
8189
8190     static const float quad[][7] = {
8191         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
8192         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
8193         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
8194         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
8195     };
8196
8197     static const D3DVERTEXELEMENT9 decl_elements[] = {
8198         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8199         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8200         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8201         D3DDECL_END()
8202     };
8203
8204     /* use asymmetric matrix to test loading */
8205     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
8206     float scale, offset;
8207
8208     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
8209     IDirect3DTexture9           *texture            = NULL;
8210
8211     memset(&caps, 0, sizeof(caps));
8212     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8213     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8214     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
8215         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
8216         return;
8217     } else {
8218         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
8219          * They report that it is not supported, but after that bump mapping works properly. So just test
8220          * if the format is generally supported, and check the BUMPENVMAP flag
8221          */
8222         IDirect3D9 *d3d9;
8223
8224         IDirect3DDevice9_GetDirect3D(device, &d3d9);
8225         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8226                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
8227         L6V5U5_supported = SUCCEEDED(hr);
8228         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
8229                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
8230         IDirect3D9_Release(d3d9);
8231         if(FAILED(hr)) {
8232             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
8233             return;
8234         }
8235     }
8236
8237     /* Generate the textures */
8238     generate_bumpmap_textures(device);
8239
8240     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
8241     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8242     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
8243     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8244     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
8245     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8246     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8247     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8248
8249     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8250     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8251     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8252     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8253     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8254     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8255
8256     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8257     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8258     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8259     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8260     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8261     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8262
8263     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8264     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8265
8266     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8267     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8268
8269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8270     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8271
8272
8273     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8274     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8275     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8276     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8277
8278     hr = IDirect3DDevice9_BeginScene(device);
8279     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8280
8281     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8282     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8283
8284     hr = IDirect3DDevice9_EndScene(device);
8285     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8286
8287     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8288      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8289      * But since testing the color match is not the purpose of the test don't be too picky
8290      */
8291     color = getPixelColor(device, 320-32, 240);
8292     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8293     color = getPixelColor(device, 320+32, 240);
8294     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8295     color = getPixelColor(device, 320, 240-32);
8296     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8297     color = getPixelColor(device, 320, 240+32);
8298     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8299     color = getPixelColor(device, 320, 240);
8300     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8301     color = getPixelColor(device, 320+32, 240+32);
8302     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8303     color = getPixelColor(device, 320-32, 240+32);
8304     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8305     color = getPixelColor(device, 320+32, 240-32);
8306     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8307     color = getPixelColor(device, 320-32, 240-32);
8308     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8309     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8310     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8311
8312     for(i = 0; i < 2; i++) {
8313         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8314         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8315         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8316         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8317         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8318         IDirect3DTexture9_Release(texture); /* To destroy it */
8319     }
8320
8321     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8322         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8323         goto cleanup;
8324     }
8325     if(L6V5U5_supported == FALSE) {
8326         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8327         goto cleanup;
8328     }
8329
8330     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8331     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8332     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8333      * would only make this test more complicated
8334      */
8335     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8336     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8337     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8339
8340     memset(&locked_rect, 0, sizeof(locked_rect));
8341     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8342     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8343     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8344     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8345     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8346
8347     memset(&locked_rect, 0, sizeof(locked_rect));
8348     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8349     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8350     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8351     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8352     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8353
8354     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8355     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8356     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8357     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8358
8359     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8360     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8361     scale = 2.0;
8362     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8363     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8364     offset = 0.1;
8365     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8366     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8367
8368     hr = IDirect3DDevice9_BeginScene(device);
8369     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8370     if(SUCCEEDED(hr)) {
8371         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8372         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8373         hr = IDirect3DDevice9_EndScene(device);
8374         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8375     }
8376
8377     color = getPixelColor(device, 320, 240);
8378     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8379      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8380      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8381      */
8382     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8383     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8384     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8385
8386     /* Check a result scale factor > 1.0 */
8387     scale = 10;
8388     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8389     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8390     offset = 10;
8391     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8392     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8393
8394     hr = IDirect3DDevice9_BeginScene(device);
8395     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8396     if(SUCCEEDED(hr)) {
8397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8398         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8399         hr = IDirect3DDevice9_EndScene(device);
8400         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8401     }
8402     color = getPixelColor(device, 320, 240);
8403     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8404     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8405     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8406
8407     /* Check clamping in the scale factor calculation */
8408     scale = 1000;
8409     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8410     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8411     offset = -1;
8412     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8413     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8414
8415     hr = IDirect3DDevice9_BeginScene(device);
8416     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8417     if(SUCCEEDED(hr)) {
8418         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8419         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8420         hr = IDirect3DDevice9_EndScene(device);
8421         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8422     }
8423     color = getPixelColor(device, 320, 240);
8424     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8425     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8426     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8427
8428     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8429     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8430     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8431     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8432
8433     IDirect3DTexture9_Release(tex1);
8434     IDirect3DTexture9_Release(tex2);
8435
8436 cleanup:
8437     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8438     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8439     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8440     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8441
8442     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8443     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8444     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8445 }
8446
8447 static void stencil_cull_test(IDirect3DDevice9 *device) {
8448     HRESULT hr;
8449     IDirect3DSurface9 *depthstencil = NULL;
8450     D3DSURFACE_DESC desc;
8451     float quad1[] = {
8452         -1.0,   -1.0,   0.1,
8453          0.0,   -1.0,   0.1,
8454         -1.0,    0.0,   0.1,
8455          0.0,    0.0,   0.1,
8456     };
8457     float quad2[] = {
8458          0.0,   -1.0,   0.1,
8459          1.0,   -1.0,   0.1,
8460          0.0,    0.0,   0.1,
8461          1.0,    0.0,   0.1,
8462     };
8463     float quad3[] = {
8464         0.0,    0.0,   0.1,
8465         1.0,    0.0,   0.1,
8466         0.0,    1.0,   0.1,
8467         1.0,    1.0,   0.1,
8468     };
8469     float quad4[] = {
8470         -1.0,    0.0,   0.1,
8471          0.0,    0.0,   0.1,
8472         -1.0,    1.0,   0.1,
8473          0.0,    1.0,   0.1,
8474     };
8475     struct vertex painter[] = {
8476        {-1.0,   -1.0,   0.0,    0x00000000},
8477        { 1.0,   -1.0,   0.0,    0x00000000},
8478        {-1.0,    1.0,   0.0,    0x00000000},
8479        { 1.0,    1.0,   0.0,    0x00000000},
8480     };
8481     WORD indices_cw[]  = {0, 1, 3};
8482     WORD indices_ccw[] = {0, 2, 3};
8483     unsigned int i;
8484     DWORD color;
8485
8486     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8487     if(depthstencil == NULL) {
8488         skip("No depth stencil buffer\n");
8489         return;
8490     }
8491     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8492     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8493     IDirect3DSurface9_Release(depthstencil);
8494     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8495         skip("No 4 or 8 bit stencil surface\n");
8496         return;
8497     }
8498
8499     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8500     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8501     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8502
8503     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8504     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8505     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8506     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8507     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8508     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8511
8512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8513     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8514     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8515     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8516     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8517     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8518
8519     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8520     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8521     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8522     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8523
8524     /* First pass: Fill the stencil buffer with some values... */
8525     hr = IDirect3DDevice9_BeginScene(device);
8526     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8527     if(SUCCEEDED(hr))
8528     {
8529         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8530         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8531         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8532                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8533         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8534         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8535                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8536         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8537
8538         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8539         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8540         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8541         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8542         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8543                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8544         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8545         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8546                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8547         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8548
8549         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8550         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8551         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8552                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8553         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8554         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8555                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8556         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8557
8558         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8559         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8560         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8561                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8562         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8563         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8564                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8565         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8566
8567         hr = IDirect3DDevice9_EndScene(device);
8568         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8569     }
8570
8571     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8572     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8573     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8574     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8577     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8578     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8579     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8582     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8583     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8584
8585     /* 2nd pass: Make the stencil values visible */
8586     hr = IDirect3DDevice9_BeginScene(device);
8587     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8588     if(SUCCEEDED(hr))
8589     {
8590         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8591         for(i = 0; i < 16; i++) {
8592             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8593             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8594
8595             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8596             painter[1].diffuse = (i * 16);
8597             painter[2].diffuse = (i * 16);
8598             painter[3].diffuse = (i * 16);
8599             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8600             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8601         }
8602         hr = IDirect3DDevice9_EndScene(device);
8603         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8604     }
8605
8606     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8607     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8608
8609     color = getPixelColor(device, 160, 420);
8610     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8611     color = getPixelColor(device, 160, 300);
8612     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8613
8614     color = getPixelColor(device, 480, 420);
8615     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8616     color = getPixelColor(device, 480, 300);
8617     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8618
8619     color = getPixelColor(device, 160, 180);
8620     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8621     color = getPixelColor(device, 160, 60);
8622     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8623
8624     color = getPixelColor(device, 480, 180);
8625     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8626     color = getPixelColor(device, 480, 60);
8627     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8628
8629     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8630     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8631 }
8632
8633 static void vpos_register_test(IDirect3DDevice9 *device)
8634 {
8635     HRESULT hr;
8636     DWORD color;
8637     const DWORD shader_code[] = {
8638     0xffff0300,                                                             /* ps_3_0                     */
8639     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8640     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8641     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8642     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8643     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8644     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8645     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8646     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8647     0x0000ffff                                                              /* end                        */
8648     };
8649     const DWORD shader_frac_code[] = {
8650     0xffff0300,                                                             /* ps_3_0                     */
8651     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8652     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8653     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8654     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8655     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8656     0x0000ffff                                                              /* end                        */
8657     };
8658     IDirect3DPixelShader9 *shader, *shader_frac;
8659     IDirect3DSurface9 *surface = NULL, *backbuffer;
8660     const float quad[] = {
8661         -1.0,   -1.0,   0.1,    0.0,    0.0,
8662          1.0,   -1.0,   0.1,    1.0,    0.0,
8663         -1.0,    1.0,   0.1,    0.0,    1.0,
8664          1.0,    1.0,   0.1,    1.0,    1.0,
8665     };
8666     D3DLOCKED_RECT lr;
8667     float constant[4] = {1.0, 0.0, 320, 240};
8668     DWORD *pos;
8669
8670     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8671     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8672     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8673     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8674     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8675     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8676     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8677     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8678     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8679     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8680     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8681     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8682
8683     hr = IDirect3DDevice9_BeginScene(device);
8684     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8685     if(SUCCEEDED(hr)) {
8686         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8687         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8688         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8689         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8690         hr = IDirect3DDevice9_EndScene(device);
8691         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8692     }
8693
8694     /* This has to be pixel exact */
8695     color = getPixelColor(device, 319, 239);
8696     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8697     color = getPixelColor(device, 320, 239);
8698     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8699     color = getPixelColor(device, 319, 240);
8700     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8701     color = getPixelColor(device, 320, 240);
8702     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8703     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8704
8705     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8706                                              &surface, NULL);
8707     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8708     hr = IDirect3DDevice9_BeginScene(device);
8709     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8710     if(SUCCEEDED(hr)) {
8711         constant[2] = 16; constant[3] = 16;
8712         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8713         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8714         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8715         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8716         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8717         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8718         hr = IDirect3DDevice9_EndScene(device);
8719         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8720     }
8721     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8722     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8723
8724     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8725     color = *pos & 0x00ffffff;
8726     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8727     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8728     color = *pos & 0x00ffffff;
8729     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8730     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8731     color = *pos & 0x00ffffff;
8732     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8733     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8734     color = *pos & 0x00ffffff;
8735     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8736
8737     hr = IDirect3DSurface9_UnlockRect(surface);
8738     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8739
8740     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8741      * have full control over the multisampling setting inside this test
8742      */
8743     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8744     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8745     hr = IDirect3DDevice9_BeginScene(device);
8746     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8747     if(SUCCEEDED(hr)) {
8748         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8749         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8750         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8751         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8752         hr = IDirect3DDevice9_EndScene(device);
8753         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8754     }
8755     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8756     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8757
8758     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8759     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8760
8761     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8762     color = *pos & 0x00ffffff;
8763     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8764
8765     hr = IDirect3DSurface9_UnlockRect(surface);
8766     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8767
8768     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8769     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8770     IDirect3DPixelShader9_Release(shader);
8771     IDirect3DPixelShader9_Release(shader_frac);
8772     if(surface) IDirect3DSurface9_Release(surface);
8773     IDirect3DSurface9_Release(backbuffer);
8774 }
8775
8776 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8777 {
8778     D3DCOLOR color;
8779
8780     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8781     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8782     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8783     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8784     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8785
8786     ++r;
8787     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8788     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8789     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8790     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8791     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8792
8793     return TRUE;
8794 }
8795
8796 static void pointsize_test(IDirect3DDevice9 *device)
8797 {
8798     HRESULT hr;
8799     D3DCAPS9 caps;
8800     D3DMATRIX matrix;
8801     D3DMATRIX identity;
8802     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8803     DWORD color;
8804     IDirect3DSurface9 *rt, *backbuffer;
8805     IDirect3DTexture9 *tex1, *tex2;
8806     RECT rect = {0, 0, 128, 128};
8807     D3DLOCKED_RECT lr;
8808     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8809                                 0x00000000, 0x00000000};
8810     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8811                                 0x00000000, 0x0000ff00};
8812
8813     const float vertices[] = {
8814         64,     64,     0.1,
8815         128,    64,     0.1,
8816         192,    64,     0.1,
8817         256,    64,     0.1,
8818         320,    64,     0.1,
8819         384,    64,     0.1,
8820         448,    64,     0.1,
8821         512,    64,     0.1,
8822     };
8823
8824     /* 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 */
8825     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;
8826     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;
8827     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;
8828     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;
8829
8830     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;
8831     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;
8832     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;
8833     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;
8834
8835     memset(&caps, 0, sizeof(caps));
8836     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8837     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8838     if(caps.MaxPointSize < 32.0) {
8839         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8840         return;
8841     }
8842
8843     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8844     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8845     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8846     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8847     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8848     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8849     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8850     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8851
8852     hr = IDirect3DDevice9_BeginScene(device);
8853     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8854     if (SUCCEEDED(hr))
8855     {
8856         ptsize = 15.0;
8857         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8858         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8859         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8860         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8861
8862         ptsize = 31.0;
8863         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8864         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8865         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8866         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8867
8868         ptsize = 30.75;
8869         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8870         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8871         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8872         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8873
8874         if (caps.MaxPointSize >= 63.0)
8875         {
8876             ptsize = 63.0;
8877             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8878             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8879             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8880             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8881
8882             ptsize = 62.75;
8883             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8884             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8885             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8886             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8887         }
8888
8889         ptsize = 1.0;
8890         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8891         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8892         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8893         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8894
8895         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8896         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8897         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8898         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8899
8900         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8901         ptsize = 15.0;
8902         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8903         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8904         ptsize = 1.0;
8905         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8906         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8907         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8908         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8909
8910         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8911         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8912
8913         /* pointsize < pointsize_min < pointsize_max?
8914          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8915         ptsize = 1.0;
8916         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8917         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8918         ptsize = 15.0;
8919         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8920         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8921         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8922         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8923
8924         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8925         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8926
8927         hr = IDirect3DDevice9_EndScene(device);
8928         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8929     }
8930
8931     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8932     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8933     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8934
8935     if (caps.MaxPointSize >= 63.0)
8936     {
8937         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8938         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8939     }
8940
8941     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8942     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8943     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8944     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8945     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8946
8947     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8948
8949     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8950      * generates texture coordinates for the point(result: Yes, it does)
8951      *
8952      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8953      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8954      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8955      */
8956     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8957     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8958
8959     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8960     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8961     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8962     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8963     memset(&lr, 0, sizeof(lr));
8964     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8965     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8966     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8967     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8968     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8969     memset(&lr, 0, sizeof(lr));
8970     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8971     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8972     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8973     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8974     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8976     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8978     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8979     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8980     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8981     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8982     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8983     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8984     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8985     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8986     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8987     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8988     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8989
8990     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8991     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8992     ptsize = 32.0;
8993     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8994     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8995
8996     hr = IDirect3DDevice9_BeginScene(device);
8997     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8998     if(SUCCEEDED(hr))
8999     {
9000         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9001         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9002         hr = IDirect3DDevice9_EndScene(device);
9003         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9004     }
9005
9006     color = getPixelColor(device, 64-4, 64-4);
9007     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
9008     color = getPixelColor(device, 64-4, 64+4);
9009     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
9010     color = getPixelColor(device, 64+4, 64+4);
9011     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
9012     color = getPixelColor(device, 64+4, 64-4);
9013     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
9014     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9015
9016     U(matrix).m[0][0] =  1.0f / 64.0f;
9017     U(matrix).m[1][1] = -1.0f / 64.0f;
9018     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
9019     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
9020
9021     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
9022     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
9023
9024     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
9025             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
9026     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
9027
9028     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
9029     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9030     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
9031     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
9032
9033     hr = IDirect3DDevice9_BeginScene(device);
9034     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
9035     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
9036     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
9037     hr = IDirect3DDevice9_EndScene(device);
9038     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
9039
9040     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
9041     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
9042     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9043     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
9044     IDirect3DSurface9_Release(backbuffer);
9045     IDirect3DSurface9_Release(rt);
9046
9047     color = getPixelColor(device, 64-4, 64-4);
9048     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
9049             "Expected color 0x00ff0000, got 0x%08x.\n", color);
9050     color = getPixelColor(device, 64+4, 64-4);
9051     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
9052             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9053     color = getPixelColor(device, 64-4, 64+4);
9054     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
9055             "Expected color 0x00000000, got 0x%08x.\n", color);
9056     color = getPixelColor(device, 64+4, 64+4);
9057     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
9058             "Expected color 0x0000ff00, got 0x%08x.\n", color);
9059
9060     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9061     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9062
9063     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9064     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9065     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9066     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
9067     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9068     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9069     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9070     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9071     IDirect3DTexture9_Release(tex1);
9072     IDirect3DTexture9_Release(tex2);
9073
9074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
9075     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9076     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
9077     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
9078     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
9079     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
9080 }
9081
9082 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
9083 {
9084     HRESULT hr;
9085     IDirect3DPixelShader9 *ps;
9086     IDirect3DTexture9 *tex1, *tex2;
9087     IDirect3DSurface9 *surf1, *surf2, *backbuf;
9088     D3DCAPS9 caps;
9089     DWORD color;
9090     DWORD shader_code[] = {
9091     0xffff0300,                                                             /* ps_3_0             */
9092     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
9093     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
9094     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
9095     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
9096     0x0000ffff                                                              /* END                */
9097     };
9098     float quad[] = {
9099        -1.0,   -1.0,    0.1,
9100         1.0,   -1.0,    0.1,
9101        -1.0,    1.0,    0.1,
9102         1.0,    1.0,    0.1,
9103     };
9104     float texquad[] = {
9105        -1.0,   -1.0,    0.1,    0.0,    0.0,
9106         0.0,   -1.0,    0.1,    1.0,    0.0,
9107        -1.0,    1.0,    0.1,    0.0,    1.0,
9108         0.0,    1.0,    0.1,    1.0,    1.0,
9109
9110         0.0,   -1.0,    0.1,    0.0,    0.0,
9111         1.0,   -1.0,    0.1,    1.0,    0.0,
9112         0.0,    1.0,    0.1,    0.0,    1.0,
9113         1.0,    1.0,    0.1,    1.0,    1.0,
9114     };
9115
9116     memset(&caps, 0, sizeof(caps));
9117     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9118     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
9119     if(caps.NumSimultaneousRTs < 2) {
9120         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
9121         return;
9122     }
9123
9124     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
9125     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9126
9127     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
9128     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9129     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
9130     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9131     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
9132     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
9133
9134     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
9135     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
9136     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
9137     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9138     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
9139     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
9140
9141     hr = IDirect3DDevice9_SetPixelShader(device, ps);
9142     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9143     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
9144     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9145     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
9146     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9147     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9148     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9149
9150     hr = IDirect3DDevice9_BeginScene(device);
9151     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
9152     if(SUCCEEDED(hr)) {
9153         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
9154         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9155
9156         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9157         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
9158         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
9159         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9160         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
9161         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
9162         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9163         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
9164
9165         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9166         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9167         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
9168         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9169
9170         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
9171         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9172         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
9173         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
9174
9175         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9176         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
9177
9178         hr = IDirect3DDevice9_EndScene(device);
9179         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
9180     }
9181
9182     color = getPixelColor(device, 160, 240);
9183     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
9184     color = getPixelColor(device, 480, 240);
9185     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
9186     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9187
9188     IDirect3DPixelShader9_Release(ps);
9189     IDirect3DTexture9_Release(tex1);
9190     IDirect3DTexture9_Release(tex2);
9191     IDirect3DSurface9_Release(surf1);
9192     IDirect3DSurface9_Release(surf2);
9193     IDirect3DSurface9_Release(backbuf);
9194 }
9195
9196 struct formats {
9197     const char *fmtName;
9198     D3DFORMAT textureFormat;
9199     DWORD resultColorBlending;
9200     DWORD resultColorNoBlending;
9201 };
9202
9203 const struct formats test_formats[] = {
9204   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
9205   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
9206   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
9207   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
9208   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
9209   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
9210   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
9211   { NULL, 0 }
9212 };
9213
9214 static void pixelshader_blending_test(IDirect3DDevice9 *device)
9215 {
9216     HRESULT hr;
9217     IDirect3DTexture9 *offscreenTexture = NULL;
9218     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
9219     IDirect3D9 *d3d = NULL;
9220     DWORD color;
9221     DWORD r0, g0, b0, r1, g1, b1;
9222     int fmt_index;
9223
9224     static const float quad[][5] = {
9225         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
9226         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9227         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9228         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9229     };
9230
9231     /* Quad with R=0x10, G=0x20 */
9232     static const struct vertex quad1[] = {
9233         {-1.0f, -1.0f, 0.1f, 0x80102000},
9234         {-1.0f,  1.0f, 0.1f, 0x80102000},
9235         { 1.0f, -1.0f, 0.1f, 0x80102000},
9236         { 1.0f,  1.0f, 0.1f, 0x80102000},
9237     };
9238
9239     /* Quad with R=0x20, G=0x10 */
9240     static const struct vertex quad2[] = {
9241         {-1.0f, -1.0f, 0.1f, 0x80201000},
9242         {-1.0f,  1.0f, 0.1f, 0x80201000},
9243         { 1.0f, -1.0f, 0.1f, 0x80201000},
9244         { 1.0f,  1.0f, 0.1f, 0x80201000},
9245     };
9246
9247     IDirect3DDevice9_GetDirect3D(device, &d3d);
9248
9249     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9250     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9251     if(!backbuffer) {
9252         goto out;
9253     }
9254
9255     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9256     {
9257         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9258         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9259            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9260            continue;
9261         }
9262
9263         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9264         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9265
9266         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9267         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9268         if(!offscreenTexture) {
9269             continue;
9270         }
9271
9272         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9273         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9274         if(!offscreen) {
9275             continue;
9276         }
9277
9278         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9279         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9280
9281         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9282         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9283         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9284         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9285         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9286         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9287         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9288         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9289         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9290         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9291
9292         /* Below we will draw two quads with different colors and try to blend them together.
9293          * The result color is compared with the expected outcome.
9294          */
9295         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9296             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9297             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9298             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9299             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9300
9301             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9302             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9303
9304             /* Draw a quad using color 0x0010200 */
9305             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9306             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9307             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9308             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9309             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9310             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9311
9312             /* Draw a quad using color 0x0020100 */
9313             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9314             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9315             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9316             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9317             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9318             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9319
9320             /* We don't want to blend the result on the backbuffer */
9321             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9322             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9323
9324             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9325             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9326             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9327             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9328             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9329
9330             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9331             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9332
9333             /* This time with the texture */
9334             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9335             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9336
9337             IDirect3DDevice9_EndScene(device);
9338         }
9339
9340         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9341             /* Compare the color of the center quad with our expectation */
9342             color = getPixelColor(device, 320, 240);
9343             r0 = (color & 0x00ff0000) >> 16;
9344             g0 = (color & 0x0000ff00) >>  8;
9345             b0 = (color & 0x000000ff) >>  0;
9346
9347             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9348             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9349             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9350
9351             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9352                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9353                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9354                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9355         } else {
9356             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9357              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9358              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9359             color = getPixelColor(device, 320, 240);
9360             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);
9361         }
9362         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9363
9364         IDirect3DDevice9_SetTexture(device, 0, NULL);
9365         if(offscreenTexture) {
9366             IDirect3DTexture9_Release(offscreenTexture);
9367         }
9368         if(offscreen) {
9369             IDirect3DSurface9_Release(offscreen);
9370         }
9371     }
9372
9373 out:
9374     /* restore things */
9375     if(backbuffer) {
9376         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9377         IDirect3DSurface9_Release(backbuffer);
9378     }
9379 }
9380
9381 static void tssargtemp_test(IDirect3DDevice9 *device)
9382 {
9383     HRESULT hr;
9384     DWORD color;
9385     static const struct vertex quad[] = {
9386         {-1.0,     -1.0,    0.1,    0x00ff0000},
9387         { 1.0,     -1.0,    0.1,    0x00ff0000},
9388         {-1.0,      1.0,    0.1,    0x00ff0000},
9389         { 1.0,      1.0,    0.1,    0x00ff0000}
9390     };
9391     D3DCAPS9 caps;
9392
9393     memset(&caps, 0, sizeof(caps));
9394     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9395     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9396     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9397         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9398         return;
9399     }
9400
9401     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9402     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9403
9404     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9405     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9406     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9407     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9408
9409     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9410     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9411     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9412     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9413     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9414     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9415
9416     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9417     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9418     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9419     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9420     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9421     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9422
9423     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9424     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9425
9426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9428     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9429     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9430
9431     hr = IDirect3DDevice9_BeginScene(device);
9432     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9433     if(SUCCEEDED(hr)) {
9434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9436         hr = IDirect3DDevice9_EndScene(device);
9437         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9438     }
9439     color = getPixelColor(device, 320, 240);
9440     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9441     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9442
9443     /* Set stage 1 back to default */
9444     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9445     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9446     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9447     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9448     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9449     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9450     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9451     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9452     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9453     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9454 }
9455
9456 struct testdata
9457 {
9458     DWORD idxVertex; /* number of instances in the first stream */
9459     DWORD idxColor; /* number of instances in the second stream */
9460     DWORD idxInstance; /* should be 1 ?? */
9461     DWORD color1; /* color 1 instance */
9462     DWORD color2; /* color 2 instance */
9463     DWORD color3; /* color 3 instance */
9464     DWORD color4; /* color 4 instance */
9465     WORD strVertex; /* specify which stream to use 0-2*/
9466     WORD strColor;
9467     WORD strInstance;
9468 };
9469
9470 static const struct testdata testcases[]=
9471 {
9472     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9473     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9474     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9475     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9476     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9477     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9478     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9479     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9480     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9481     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9482     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9483     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9484     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9485     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9486     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9487 /*
9488     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9489     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9490 */
9491 };
9492
9493 /* Drawing Indexed Geometry with instances*/
9494 static void stream_test(IDirect3DDevice9 *device)
9495 {
9496     IDirect3DVertexBuffer9 *vb = NULL;
9497     IDirect3DVertexBuffer9 *vb2 = NULL;
9498     IDirect3DVertexBuffer9 *vb3 = NULL;
9499     IDirect3DIndexBuffer9 *ib = NULL;
9500     IDirect3DVertexDeclaration9 *pDecl = NULL;
9501     IDirect3DVertexShader9 *shader = NULL;
9502     HRESULT hr;
9503     BYTE *data;
9504     DWORD color;
9505     DWORD ind;
9506     unsigned i;
9507
9508     const DWORD shader_code[] =
9509     {
9510         0xfffe0101,                                     /* vs_1_1 */
9511         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9512         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9513         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9514         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9515         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9516         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9517         0x0000ffff
9518     };
9519
9520     const float quad[][3] =
9521     {
9522         {-0.5f, -0.5f,  1.1f}, /*0 */
9523         {-0.5f,  0.5f,  1.1f}, /*1 */
9524         { 0.5f, -0.5f,  1.1f}, /*2 */
9525         { 0.5f,  0.5f,  1.1f}, /*3 */
9526     };
9527
9528     const float vertcolor[][4] =
9529     {
9530         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9531         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9532         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9533         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9534     };
9535
9536     /* 4 position for 4 instances */
9537     const float instancepos[][3] =
9538     {
9539         {-0.6f,-0.6f, 0.0f},
9540         { 0.6f,-0.6f, 0.0f},
9541         { 0.6f, 0.6f, 0.0f},
9542         {-0.6f, 0.6f, 0.0f},
9543     };
9544
9545     short indices[] = {0, 1, 2, 1, 2, 3};
9546
9547     D3DVERTEXELEMENT9 decl[] =
9548     {
9549         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9550         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9551         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9552         D3DDECL_END()
9553     };
9554
9555     /* set the default value because it isn't done in wine? */
9556     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9557     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9558
9559     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9560     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9561     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9562
9563     /* check wrong cases */
9564     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9565     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9566     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9567     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9568     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9569     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9570     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9571     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9572     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9573     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9574     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9575     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9576     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9577     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9578     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9579     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9580     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9581     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9582     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9583     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9584
9585     /* set the default value back */
9586     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9587     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9588
9589     /* create all VertexBuffers*/
9590     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9591     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9592     if(!vb) {
9593         skip("Failed to create a vertex buffer\n");
9594         return;
9595     }
9596     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9597     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9598     if(!vb2) {
9599         skip("Failed to create a vertex buffer\n");
9600         goto out;
9601     }
9602     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9603     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9604     if(!vb3) {
9605         skip("Failed to create a vertex buffer\n");
9606         goto out;
9607     }
9608
9609     /* create IndexBuffer*/
9610     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9611     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9612     if(!ib) {
9613         skip("Failed to create a index buffer\n");
9614         goto out;
9615     }
9616
9617     /* copy all Buffers (Vertex + Index)*/
9618     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9619     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9620     memcpy(data, quad, sizeof(quad));
9621     hr = IDirect3DVertexBuffer9_Unlock(vb);
9622     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9623     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9624     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9625     memcpy(data, vertcolor, sizeof(vertcolor));
9626     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9627     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9628     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9629     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9630     memcpy(data, instancepos, sizeof(instancepos));
9631     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9632     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9633     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9634     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9635     memcpy(data, indices, sizeof(indices));
9636     hr = IDirect3DIndexBuffer9_Unlock(ib);
9637     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9638
9639     /* create VertexShader */
9640     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9641     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9642     if(!shader) {
9643         skip("Failed to create a vetex shader\n");
9644         goto out;
9645     }
9646
9647     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9648     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9649
9650     hr = IDirect3DDevice9_SetIndices(device, ib);
9651     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9652
9653     /* run all tests */
9654     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9655     {
9656         struct testdata act = testcases[i];
9657         decl[0].Stream = act.strVertex;
9658         decl[1].Stream = act.strColor;
9659         decl[2].Stream = act.strInstance;
9660         /* create VertexDeclarations */
9661         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9662         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9663
9664         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9665         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9666
9667         hr = IDirect3DDevice9_BeginScene(device);
9668         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9669         if(SUCCEEDED(hr))
9670         {
9671             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9672             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9673
9674             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9675             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9676             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9677             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9678
9679             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9680             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9681             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9682             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9683
9684             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9685             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9686             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9687             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9688
9689             /* don't know if this is right (1*3 and 4*1)*/
9690             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9691             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9692             hr = IDirect3DDevice9_EndScene(device);
9693             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9694
9695             /* set all StreamSource && StreamSourceFreq back to default */
9696             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9697             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9698             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9699             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9700             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9701             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9702             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9703             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9704             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9705             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9706             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9707             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9708         }
9709
9710         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9711         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9712
9713         color = getPixelColor(device, 160, 360);
9714         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9715         color = getPixelColor(device, 480, 360);
9716         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9717         color = getPixelColor(device, 480, 120);
9718         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9719         color = getPixelColor(device, 160, 120);
9720         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9721
9722         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9723         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9724     }
9725
9726     hr = IDirect3DDevice9_SetIndices(device, NULL);
9727     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9728
9729 out:
9730     if(vb) IDirect3DVertexBuffer9_Release(vb);
9731     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9732     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9733     if(ib)IDirect3DIndexBuffer9_Release(ib);
9734     if(shader)IDirect3DVertexShader9_Release(shader);
9735 }
9736
9737 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9738     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9739     IDirect3DTexture9 *dsttex = NULL;
9740     HRESULT hr;
9741     DWORD color;
9742     D3DRECT r1 = {0,  0,  50,  50 };
9743     D3DRECT r2 = {50, 0,  100, 50 };
9744     D3DRECT r3 = {50, 50, 100, 100};
9745     D3DRECT r4 = {0,  50,  50, 100};
9746     const float quad[] = {
9747         -1.0,   -1.0,   0.1,    0.0,    0.0,
9748          1.0,   -1.0,   0.1,    1.0,    0.0,
9749         -1.0,    1.0,   0.1,    0.0,    1.0,
9750          1.0,    1.0,   0.1,    1.0,    1.0,
9751     };
9752
9753     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9754     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9755
9756     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9757     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9758     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9759     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9760
9761     if(!src || !dsttex) {
9762         skip("One or more test resources could not be created\n");
9763         goto cleanup;
9764     }
9765
9766     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9767     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9768
9769     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9770     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9771
9772     /* Clear the StretchRect destination for debugging */
9773     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9774     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9775     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9776     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9777
9778     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9779     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9780
9781     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9782     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9783     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9784     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9785     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9786     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9787     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9788     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9789
9790     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9791      * the target -> texture GL blit path
9792      */
9793     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9794     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9795     IDirect3DSurface9_Release(dst);
9796
9797     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9798     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9799
9800     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9801     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9802     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9803     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9804     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9805     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9806     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9807     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9808
9809     hr = IDirect3DDevice9_BeginScene(device);
9810     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9811     if(SUCCEEDED(hr)) {
9812         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9813         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9814         hr = IDirect3DDevice9_EndScene(device);
9815         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9816     }
9817
9818     color = getPixelColor(device, 160, 360);
9819     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9820     color = getPixelColor(device, 480, 360);
9821     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9822     color = getPixelColor(device, 480, 120);
9823     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9824     color = getPixelColor(device, 160, 120);
9825     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9826     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9827     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9828
9829     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9830     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9831     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9832     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9833
9834 cleanup:
9835     if(src) IDirect3DSurface9_Release(src);
9836     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9837     if(dsttex) IDirect3DTexture9_Release(dsttex);
9838 }
9839
9840 static void texop_test(IDirect3DDevice9 *device)
9841 {
9842     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9843     IDirect3DTexture9 *texture = NULL;
9844     D3DLOCKED_RECT locked_rect;
9845     D3DCOLOR color;
9846     D3DCAPS9 caps;
9847     HRESULT hr;
9848     unsigned i;
9849
9850     static const struct {
9851         float x, y, z;
9852         float s, t;
9853         D3DCOLOR diffuse;
9854     } quad[] = {
9855         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9856         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9857         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9858         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9859     };
9860
9861     static const D3DVERTEXELEMENT9 decl_elements[] = {
9862         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9863         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9864         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9865         D3DDECL_END()
9866     };
9867
9868     static const struct {
9869         D3DTEXTUREOP op;
9870         const char *name;
9871         DWORD caps_flag;
9872         D3DCOLOR result;
9873     } test_data[] = {
9874         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9875         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9876         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9877         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9878         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9879         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9880         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9881         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9882         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9883         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9884         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9885         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9886         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9887         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9888         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9889         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9890         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9891         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9892         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9893         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9894         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9895         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9896         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9897     };
9898
9899     memset(&caps, 0, sizeof(caps));
9900     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9901     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9902
9903     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9904     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9905     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9906     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9907
9908     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9909     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9910     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9911     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9912     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9913     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9914     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9915     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9916     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9917
9918     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9919     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9920     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9921     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9922     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9923     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9924
9925     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9926     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9927
9928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9929     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9931     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9932     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9933     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9934
9935     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9936     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9937
9938     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9939     {
9940         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9941         {
9942             skip("tex operation %s not supported\n", test_data[i].name);
9943             continue;
9944         }
9945
9946         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9947         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9948
9949         hr = IDirect3DDevice9_BeginScene(device);
9950         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9951
9952         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9953         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9954
9955         hr = IDirect3DDevice9_EndScene(device);
9956         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9957
9958         color = getPixelColor(device, 320, 240);
9959         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9960                 test_data[i].name, color, test_data[i].result);
9961
9962         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9964     }
9965
9966     if (texture) IDirect3DTexture9_Release(texture);
9967     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9968 }
9969
9970 static void yuv_color_test(IDirect3DDevice9 *device) {
9971     HRESULT hr;
9972     IDirect3DSurface9 *surface = NULL, *target = NULL;
9973     unsigned int fmt, i;
9974     D3DFORMAT format;
9975     const char *fmt_string;
9976     D3DLOCKED_RECT lr;
9977     IDirect3D9 *d3d;
9978     HRESULT color;
9979     DWORD ref_color_left, ref_color_right;
9980
9981     struct {
9982         DWORD in;           /* The input color */
9983         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9984         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9985         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9986         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9987     } test_data[] = {
9988     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9989      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9990      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9991      * that
9992      */
9993       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9994       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9995       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9996       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9997       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9998       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9999       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
10000       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
10001       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
10002       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
10003       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
10004       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
10005       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
10006       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
10007
10008       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
10009       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
10010       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
10011       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
10012     };
10013
10014     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
10015     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
10016     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
10017     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
10018
10019     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
10020     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
10021
10022     for(fmt = 0; fmt < 2; fmt++) {
10023         if(fmt == 0) {
10024             format = D3DFMT_UYVY;
10025             fmt_string = "D3DFMT_UYVY";
10026         } else {
10027             format = D3DFMT_YUY2;
10028             fmt_string = "D3DFMT_YUY2";
10029         }
10030
10031         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
10032                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
10033                        */
10034         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
10035                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
10036             skip("%s is not supported\n", fmt_string);
10037             continue;
10038         }
10039
10040         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
10041         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
10042         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
10043
10044         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
10045             if(fmt == 0) {
10046                 ref_color_left = test_data[i].uyvy_left;
10047                 ref_color_right = test_data[i].uyvy_right;
10048             } else {
10049                 ref_color_left = test_data[i].yuy2_left;
10050                 ref_color_right = test_data[i].yuy2_right;
10051             }
10052
10053             memset(&lr, 0, sizeof(lr));
10054             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
10055             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
10056             *((DWORD *) lr.pBits) = test_data[i].in;
10057             hr = IDirect3DSurface9_UnlockRect(surface);
10058             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
10059
10060             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10061             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10062             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
10063             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
10064
10065             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
10066              * prevent running into precision problems, read a far left and far right pixel. In the future we may
10067              * want to add tests for the filtered pixels as well.
10068              *
10069              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
10070              * differently, so we need a max diff of 16
10071              */
10072             color = getPixelColor(device, 40, 240);
10073             ok(color_match(color, ref_color_left, 18),
10074                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
10075                test_data[i].in, color, ref_color_left, fmt_string);
10076             color = getPixelColor(device, 600, 240);
10077             ok(color_match(color, ref_color_right, 18),
10078                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
10079                test_data[i].in, color, ref_color_right, fmt_string);
10080             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10081             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10082         }
10083         IDirect3DSurface9_Release(surface);
10084     }
10085     IDirect3DSurface9_Release(target);
10086     IDirect3D9_Release(d3d);
10087 }
10088
10089 static void texop_range_test(IDirect3DDevice9 *device)
10090 {
10091     static const struct {
10092         float x, y, z;
10093         D3DCOLOR diffuse;
10094     } quad[] = {
10095         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10096         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10097         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
10098         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
10099     };
10100     HRESULT hr;
10101     IDirect3DTexture9 *texture;
10102     D3DLOCKED_RECT locked_rect;
10103     D3DCAPS9 caps;
10104     DWORD color;
10105
10106     /* We need ADD and SUBTRACT operations */
10107     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10108     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10109     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
10110         skip("D3DTOP_ADD is not supported, skipping value range test\n");
10111         return;
10112     }
10113     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
10114         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
10115         return;
10116     }
10117
10118     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10119     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
10120     /* Stage 1: result = diffuse(=1.0) + diffuse
10121      * stage 2: result = result - tfactor(= 0.5)
10122      */
10123     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10124     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10125     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10126     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10127     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10128     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10129     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
10130     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10131     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10132     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10133     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10134     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10135     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10136     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10137
10138     hr = IDirect3DDevice9_BeginScene(device);
10139     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10140     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10141     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10142     hr = IDirect3DDevice9_EndScene(device);
10143     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10144
10145     color = getPixelColor(device, 320, 240);
10146     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
10147        color);
10148     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10149     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10150
10151     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10152     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
10153     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
10154     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
10155     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
10156     hr = IDirect3DTexture9_UnlockRect(texture, 0);
10157     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
10158     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10159     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10160
10161     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
10162      * stage 2: result = result + diffuse(1.0)
10163      */
10164     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
10165     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
10166     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10167     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10168     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10169     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10170     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
10171     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10172     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
10173     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10174     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
10175     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10176     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10177     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10178
10179     hr = IDirect3DDevice9_BeginScene(device);
10180     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
10181     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10182     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10183     hr = IDirect3DDevice9_EndScene(device);
10184     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
10185
10186     color = getPixelColor(device, 320, 240);
10187     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
10188        color);
10189     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10190     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10191
10192     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10193     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10194     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10195     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
10196     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10197     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
10198     IDirect3DTexture9_Release(texture);
10199 }
10200
10201 static void alphareplicate_test(IDirect3DDevice9 *device) {
10202     struct vertex quad[] = {
10203         { -1.0,    -1.0,    0.1,    0x80ff00ff },
10204         {  1.0,    -1.0,    0.1,    0x80ff00ff },
10205         { -1.0,     1.0,    0.1,    0x80ff00ff },
10206         {  1.0,     1.0,    0.1,    0x80ff00ff },
10207     };
10208     HRESULT hr;
10209     DWORD color;
10210
10211     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10212     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10213
10214     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10215     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10216
10217     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10218     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10219     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
10220     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10221
10222     hr = IDirect3DDevice9_BeginScene(device);
10223     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10224     if(SUCCEEDED(hr)) {
10225         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10226         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10227         hr = IDirect3DDevice9_EndScene(device);
10228         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10229     }
10230
10231     color = getPixelColor(device, 320, 240);
10232     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10233        color);
10234     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10235     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10236
10237     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10238     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10239
10240 }
10241
10242 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10243     HRESULT hr;
10244     D3DCAPS9 caps;
10245     DWORD color;
10246     struct vertex quad[] = {
10247         { -1.0,    -1.0,    0.1,    0x408080c0 },
10248         {  1.0,    -1.0,    0.1,    0x408080c0 },
10249         { -1.0,     1.0,    0.1,    0x408080c0 },
10250         {  1.0,     1.0,    0.1,    0x408080c0 },
10251     };
10252
10253     memset(&caps, 0, sizeof(caps));
10254     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10255     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10256     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10257         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10258         return;
10259     }
10260
10261     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10262     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10263
10264     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10265     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10266
10267     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10268      * mov r0.a, diffuse.a
10269      * mov r0, r0.a
10270      *
10271      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10272      * 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
10273      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10274      */
10275     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10276     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10277     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10278     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10279     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10280     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10281     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10282     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10283     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10285     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10286     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10287     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10288     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10289     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10290     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10292     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10293
10294     hr = IDirect3DDevice9_BeginScene(device);
10295     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10296     if(SUCCEEDED(hr)) {
10297         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10298         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10299         hr = IDirect3DDevice9_EndScene(device);
10300         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10301     }
10302
10303     color = getPixelColor(device, 320, 240);
10304     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10305        color);
10306     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10307     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10308
10309     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10310     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10311     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10312     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10313     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10314     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10315 }
10316
10317 static void zwriteenable_test(IDirect3DDevice9 *device) {
10318     HRESULT hr;
10319     DWORD color;
10320     struct vertex quad1[] = {
10321         { -1.0,  -1.0,  0.1,    0x00ff0000},
10322         { -1.0,   1.0,  0.1,    0x00ff0000},
10323         {  1.0,  -1.0,  0.1,    0x00ff0000},
10324         {  1.0,   1.0,  0.1,    0x00ff0000},
10325     };
10326     struct vertex quad2[] = {
10327         { -1.0,  -1.0,  0.9,    0x0000ff00},
10328         { -1.0,   1.0,  0.9,    0x0000ff00},
10329         {  1.0,  -1.0,  0.9,    0x0000ff00},
10330         {  1.0,   1.0,  0.9,    0x0000ff00},
10331     };
10332
10333     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10334     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10335
10336     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10337     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10338     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10339     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10340     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10341     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10342     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10343     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10344
10345     hr = IDirect3DDevice9_BeginScene(device);
10346     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10347     if(SUCCEEDED(hr)) {
10348         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10349          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10350          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10351          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10352          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10353          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10354          */
10355         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10356         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10357         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10358         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10360         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10361
10362         hr = IDirect3DDevice9_EndScene(device);
10363         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10364     }
10365
10366     color = getPixelColor(device, 320, 240);
10367     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10368        color);
10369     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10370     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10371
10372     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10373     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10374 }
10375
10376 static void alphatest_test(IDirect3DDevice9 *device) {
10377 #define ALPHATEST_PASSED 0x0000ff00
10378 #define ALPHATEST_FAILED 0x00ff0000
10379     struct {
10380         D3DCMPFUNC  func;
10381         DWORD       color_less;
10382         DWORD       color_equal;
10383         DWORD       color_greater;
10384     } testdata[] = {
10385         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10386         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10387         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10388         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10389         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10390         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10391         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10392         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10393     };
10394     unsigned int i, j;
10395     HRESULT hr;
10396     DWORD color;
10397     struct vertex quad[] = {
10398         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10399         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10400         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10401         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10402     };
10403     D3DCAPS9 caps;
10404
10405     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10406     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10407     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10408     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10409
10410     for(j = 0; j < 2; j++) {
10411         if(j == 1) {
10412             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10413              * the alpha test either for performance reasons(floating point RTs) or to work
10414              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10415              * codepath for ffp and shader in this case, and the test should cover both
10416              */
10417             IDirect3DPixelShader9 *ps;
10418             DWORD shader_code[] = {
10419                 0xffff0101,                                 /* ps_1_1           */
10420                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10421                 0x0000ffff                                  /* end              */
10422             };
10423             memset(&caps, 0, sizeof(caps));
10424             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10425             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10426             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10427                 break;
10428             }
10429
10430             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10431             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10432             IDirect3DDevice9_SetPixelShader(device, ps);
10433             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10434             IDirect3DPixelShader9_Release(ps);
10435         }
10436
10437         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10438             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10439             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10440
10441             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10442             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10443             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10444             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10445             hr = IDirect3DDevice9_BeginScene(device);
10446             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10447             if(SUCCEEDED(hr)) {
10448                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10449                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10450                 hr = IDirect3DDevice9_EndScene(device);
10451                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10452             }
10453             color = getPixelColor(device, 320, 240);
10454             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10455             color, testdata[i].color_less, testdata[i].func);
10456             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10457             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10458
10459             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10460             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10461             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10462             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10463             hr = IDirect3DDevice9_BeginScene(device);
10464             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10465             if(SUCCEEDED(hr)) {
10466                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10467                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10468                 hr = IDirect3DDevice9_EndScene(device);
10469                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10470             }
10471             color = getPixelColor(device, 320, 240);
10472             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10473             color, testdata[i].color_equal, testdata[i].func);
10474             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10475             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10476
10477             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10478             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10479             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10480             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10481             hr = IDirect3DDevice9_BeginScene(device);
10482             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10483             if(SUCCEEDED(hr)) {
10484                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10485                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10486                 hr = IDirect3DDevice9_EndScene(device);
10487                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10488             }
10489             color = getPixelColor(device, 320, 240);
10490             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10491             color, testdata[i].color_greater, testdata[i].func);
10492             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10493             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10494         }
10495     }
10496
10497     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10498     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10499     IDirect3DDevice9_SetPixelShader(device, NULL);
10500     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10501 }
10502
10503 static void sincos_test(IDirect3DDevice9 *device) {
10504     const DWORD sin_shader_code[] = {
10505         0xfffe0200,                                                                 /* vs_2_0                       */
10506         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10507         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10508         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10509         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10510         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10511         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10512         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10513         0x0000ffff                                                                  /* end                          */
10514     };
10515     const DWORD cos_shader_code[] = {
10516         0xfffe0200,                                                                 /* vs_2_0                       */
10517         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10518         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10519         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10520         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10521         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10522         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10523         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10524         0x0000ffff                                                                  /* end                          */
10525     };
10526     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10527     HRESULT hr;
10528     struct {
10529         float x, y, z;
10530     } data[1280];
10531     unsigned int i;
10532     float sincosc1[4] = {D3DSINCOSCONST1};
10533     float sincosc2[4] = {D3DSINCOSCONST2};
10534
10535     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10536     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10537
10538     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10539     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10540     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10541     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10542     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10543     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10544     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10545     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10546     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10547     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10548
10549     /* Generate a point from -1 to 1 every 0.5 pixels */
10550     for(i = 0; i < 1280; i++) {
10551         data[i].x = (-640.0 + i) / 640.0;
10552         data[i].y = 0.0;
10553         data[i].z = 0.1;
10554     }
10555
10556     hr = IDirect3DDevice9_BeginScene(device);
10557     if(SUCCEEDED(hr)) {
10558         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10559         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10560         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10561         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10562
10563         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10564         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10565         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10566         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10567
10568         hr = IDirect3DDevice9_EndScene(device);
10569         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10570     }
10571     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10572     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10573     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10574
10575     IDirect3DDevice9_SetVertexShader(device, NULL);
10576     IDirect3DVertexShader9_Release(sin_shader);
10577     IDirect3DVertexShader9_Release(cos_shader);
10578 }
10579
10580 static void loop_index_test(IDirect3DDevice9 *device) {
10581     const DWORD shader_code[] = {
10582         0xfffe0200,                                                 /* vs_2_0                   */
10583         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10584         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10585         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10586         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10587         0x0000001d,                                                 /* endloop                  */
10588         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10589         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10590         0x0000ffff                                                  /* END                      */
10591     };
10592     IDirect3DVertexShader9 *shader;
10593     HRESULT hr;
10594     DWORD color;
10595     const float quad[] = {
10596         -1.0,   -1.0,   0.1,
10597          1.0,   -1.0,   0.1,
10598         -1.0,    1.0,   0.1,
10599          1.0,    1.0,   0.1
10600     };
10601     const float zero[4] = {0, 0, 0, 0};
10602     const float one[4] = {1, 1, 1, 1};
10603     int i0[4] = {2, 10, -3, 0};
10604     float values[4];
10605
10606     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10607     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10608     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10609     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10610     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10611     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10612     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10613     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10614
10615     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10616     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10617     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10618     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10619     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10620     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10621     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10622     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10623     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10624     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10625     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10626     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10627     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10628     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10629     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10630     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10631     values[0] = 1.0;
10632     values[1] = 1.0;
10633     values[2] = 0.0;
10634     values[3] = 0.0;
10635     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10636     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10637     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10638     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10639     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10640     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10641     values[0] = -1.0;
10642     values[1] = 0.0;
10643     values[2] = 0.0;
10644     values[3] = 0.0;
10645     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10646     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10647     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10648     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10649     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10650     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10651     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10652     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10653     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10654     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10655
10656     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10657     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10658
10659     hr = IDirect3DDevice9_BeginScene(device);
10660     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10661     if(SUCCEEDED(hr))
10662     {
10663         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10664         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10665         hr = IDirect3DDevice9_EndScene(device);
10666         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10667     }
10668     color = getPixelColor(device, 320, 240);
10669     ok(color_match(color, 0x0000ff00, 1),
10670        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10671     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10672     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10673
10674     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10675     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10676     IDirect3DVertexShader9_Release(shader);
10677 }
10678
10679 static void sgn_test(IDirect3DDevice9 *device) {
10680     const DWORD shader_code[] = {
10681         0xfffe0200,                                                             /* vs_2_0                       */
10682         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10683         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10684         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10685         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10686         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10687         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10688         0x0000ffff                                                              /* end                          */
10689     };
10690     IDirect3DVertexShader9 *shader;
10691     HRESULT hr;
10692     DWORD color;
10693     const float quad[] = {
10694         -1.0,   -1.0,   0.1,
10695          1.0,   -1.0,   0.1,
10696         -1.0,    1.0,   0.1,
10697          1.0,    1.0,   0.1
10698     };
10699
10700     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10701     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10702     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10703     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10704     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10705     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10706     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10707     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10708
10709     hr = IDirect3DDevice9_BeginScene(device);
10710     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10711     if(SUCCEEDED(hr))
10712     {
10713         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10714         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10715         hr = IDirect3DDevice9_EndScene(device);
10716         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10717     }
10718     color = getPixelColor(device, 320, 240);
10719     ok(color_match(color, 0x008000ff, 1),
10720        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10721     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10722     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10723
10724     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10725     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10726     IDirect3DVertexShader9_Release(shader);
10727 }
10728
10729 static void viewport_test(IDirect3DDevice9 *device) {
10730     HRESULT hr;
10731     DWORD color;
10732     D3DVIEWPORT9 vp, old_vp;
10733     BOOL draw_failed = TRUE;
10734     const float quad[] =
10735     {
10736         -0.5,   -0.5,   0.1,
10737          0.5,   -0.5,   0.1,
10738         -0.5,    0.5,   0.1,
10739          0.5,    0.5,   0.1
10740     };
10741
10742     memset(&old_vp, 0, sizeof(old_vp));
10743     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10744     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10745
10746     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10747     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10748
10749     /* Test a viewport with Width and Height bigger than the surface dimensions
10750      *
10751      * TODO: Test Width < surface.width, but X + Width > surface.width
10752      * TODO: Test Width < surface.width, what happens with the height?
10753      *
10754      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10755      * and Height fields bigger than the framebuffer. However, it later refuses
10756      * to draw.
10757      */
10758     memset(&vp, 0, sizeof(vp));
10759     vp.X = 0;
10760     vp.Y = 0;
10761     vp.Width = 10000;
10762     vp.Height = 10000;
10763     vp.MinZ = 0.0;
10764     vp.MaxZ = 0.0;
10765     hr = IDirect3DDevice9_SetViewport(device, &vp);
10766     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10767
10768     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10769     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10770     hr = IDirect3DDevice9_BeginScene(device);
10771     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10772     if(SUCCEEDED(hr))
10773     {
10774         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10775         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10776         draw_failed = FAILED(hr);
10777         hr = IDirect3DDevice9_EndScene(device);
10778         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10779     }
10780
10781     if(!draw_failed)
10782     {
10783         color = getPixelColor(device, 158, 118);
10784         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10785         color = getPixelColor(device, 162, 118);
10786         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10787         color = getPixelColor(device, 158, 122);
10788         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10789         color = getPixelColor(device, 162, 122);
10790         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10791
10792         color = getPixelColor(device, 478, 358);
10793         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10794         color = getPixelColor(device, 482, 358);
10795         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10796         color = getPixelColor(device, 478, 362);
10797         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10798         color = getPixelColor(device, 482, 362);
10799         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10800     }
10801
10802     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10803     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10804
10805     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10806     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10807 }
10808
10809 /* This test tests depth clamping / clipping behaviour:
10810  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10811  *   minimum/maximum z value.
10812  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10813  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10814  *   - Pretransformed vertices behave the same as regular vertices.
10815  */
10816 static void depth_clamp_test(IDirect3DDevice9 *device)
10817 {
10818     const struct tvertex quad1[] =
10819     {
10820         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10821         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10822         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10823         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10824     };
10825     const struct tvertex quad2[] =
10826     {
10827         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10828         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10829         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10830         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10831     };
10832     const struct vertex quad3[] =
10833     {
10834         {-0.65, 0.55,  5.0f,      0xffffffff},
10835         {-0.35, 0.55,  5.0f,      0xffffffff},
10836         {-0.65, 0.15,  5.0f,      0xffffffff},
10837         {-0.35, 0.15,  5.0f,      0xffffffff},
10838     };
10839     const struct vertex quad4[] =
10840     {
10841         {-0.87, 0.83, 10.0f,      0xffffffff},
10842         {-0.65, 0.83, 10.0f,      0xffffffff},
10843         {-0.87, 0.55, 10.0f,      0xffffffff},
10844         {-0.65, 0.55, 10.0f,      0xffffffff},
10845     };
10846     const struct vertex quad5[] =
10847     {
10848         { -0.5,  0.5, 10.0f,      0xff14f914},
10849         {  0.5,  0.5, 10.0f,      0xff14f914},
10850         { -0.5, -0.5, 10.0f,      0xff14f914},
10851         {  0.5, -0.5, 10.0f,      0xff14f914},
10852     };
10853     const struct tvertex quad6[] =
10854     {
10855         {    0,  120, 10.0f, 1.0, 0xfff91414},
10856         {  640,  120, 10.0f, 1.0, 0xfff91414},
10857         {    0,  180, 10.0f, 1.0, 0xfff91414},
10858         {  640,  180, 10.0f, 1.0, 0xfff91414},
10859     };
10860
10861     D3DVIEWPORT9 vp;
10862     D3DCOLOR color;
10863     HRESULT hr;
10864
10865     vp.X = 0;
10866     vp.Y = 0;
10867     vp.Width = 640;
10868     vp.Height = 480;
10869     vp.MinZ = 0.0;
10870     vp.MaxZ = 7.5;
10871
10872     hr = IDirect3DDevice9_SetViewport(device, &vp);
10873     if(FAILED(hr))
10874     {
10875         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10876          * the tests because the 7.5 is just intended to show that it doesn't have
10877          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10878          * viewport and continue.
10879          */
10880         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10881         vp.MaxZ = 1.0;
10882         hr = IDirect3DDevice9_SetViewport(device, &vp);
10883     }
10884     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10885
10886     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10887     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10888
10889     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10890     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10891     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10892     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10893     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10894     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10895     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10896     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10897
10898     hr = IDirect3DDevice9_BeginScene(device);
10899     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10900
10901     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10902     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10903
10904     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10905     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10906     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10907     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10908
10909     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10910     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10911
10912     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10913     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10914     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10915     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10916
10917     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10918     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10919
10920     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10921     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10922
10923     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10924     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10925
10926     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10927     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10928
10929     hr = IDirect3DDevice9_EndScene(device);
10930     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10931
10932     color = getPixelColor(device, 75, 75);
10933     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10934     color = getPixelColor(device, 150, 150);
10935     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10936     color = getPixelColor(device, 320, 240);
10937     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10938     color = getPixelColor(device, 320, 330);
10939     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10940     color = getPixelColor(device, 320, 330);
10941     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10942
10943     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10944     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10945
10946     vp.MinZ = 0.0;
10947     vp.MaxZ = 1.0;
10948     hr = IDirect3DDevice9_SetViewport(device, &vp);
10949     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10950 }
10951
10952 static void depth_buffer_test(IDirect3DDevice9 *device)
10953 {
10954     static const struct vertex quad1[] =
10955     {
10956         { -1.0,  1.0, 0.33f, 0xff00ff00},
10957         {  1.0,  1.0, 0.33f, 0xff00ff00},
10958         { -1.0, -1.0, 0.33f, 0xff00ff00},
10959         {  1.0, -1.0, 0.33f, 0xff00ff00},
10960     };
10961     static const struct vertex quad2[] =
10962     {
10963         { -1.0,  1.0, 0.50f, 0xffff00ff},
10964         {  1.0,  1.0, 0.50f, 0xffff00ff},
10965         { -1.0, -1.0, 0.50f, 0xffff00ff},
10966         {  1.0, -1.0, 0.50f, 0xffff00ff},
10967     };
10968     static const struct vertex quad3[] =
10969     {
10970         { -1.0,  1.0, 0.66f, 0xffff0000},
10971         {  1.0,  1.0, 0.66f, 0xffff0000},
10972         { -1.0, -1.0, 0.66f, 0xffff0000},
10973         {  1.0, -1.0, 0.66f, 0xffff0000},
10974     };
10975     static const DWORD expected_colors[4][4] =
10976     {
10977         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10978         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10979         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10980         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10981     };
10982
10983     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10984     unsigned int i, j;
10985     D3DVIEWPORT9 vp;
10986     D3DCOLOR color;
10987     HRESULT hr;
10988
10989     vp.X = 0;
10990     vp.Y = 0;
10991     vp.Width = 640;
10992     vp.Height = 480;
10993     vp.MinZ = 0.0;
10994     vp.MaxZ = 1.0;
10995
10996     hr = IDirect3DDevice9_SetViewport(device, &vp);
10997     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10998
10999     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11000     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11001     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11002     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11003     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11004     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11005     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
11006     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11007     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11008     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11009
11010     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
11011     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11012     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
11013             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
11014     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11015     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
11016             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
11017     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11018     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
11019             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
11020     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11021
11022     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
11023     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11024     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
11025     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11026
11027     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11028     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11029     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11030     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11031
11032     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
11033     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11034     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
11035     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11036
11037     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
11038     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11039     hr = IDirect3DDevice9_BeginScene(device);
11040     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11041     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
11042     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11043     hr = IDirect3DDevice9_EndScene(device);
11044     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11045
11046     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11047     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11048     IDirect3DSurface9_Release(backbuffer);
11049     IDirect3DSurface9_Release(rt3);
11050     IDirect3DSurface9_Release(rt2);
11051     IDirect3DSurface9_Release(rt1);
11052
11053     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
11054     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11055
11056     hr = IDirect3DDevice9_BeginScene(device);
11057     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11058     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
11059     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11060     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
11061     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11062     hr = IDirect3DDevice9_EndScene(device);
11063     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11064
11065     for (i = 0; i < 4; ++i)
11066     {
11067         for (j = 0; j < 4; ++j)
11068         {
11069             unsigned int x = 80 * ((2 * j) + 1);
11070             unsigned int y = 60 * ((2 * i) + 1);
11071             color = getPixelColor(device, x, y);
11072             ok(color_match(color, expected_colors[i][j], 0),
11073                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
11074         }
11075     }
11076
11077     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11078     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
11079 }
11080
11081 static void shadow_test(IDirect3DDevice9 *device)
11082 {
11083     static const DWORD ps_code[] =
11084     {
11085         0xffff0200,                                                             /* ps_2_0                       */
11086         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11087         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11088         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11089         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11090         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11091         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11092         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11093         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11094         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11095         0x0000ffff,                                                             /* end                          */
11096     };
11097     struct
11098     {
11099         D3DFORMAT format;
11100         const char *name;
11101     }
11102     formats[] =
11103     {
11104         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11105         {D3DFMT_D32,            "D3DFMT_D32"},
11106         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11107         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11108         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11109         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11110         {D3DFMT_D16,            "D3DFMT_D16"},
11111         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11112         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11113     };
11114     struct
11115     {
11116         float x, y, z;
11117         float s, t, p, q;
11118     }
11119     quad[] =
11120     {
11121         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11122         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11123         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11124         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11125     };
11126     struct
11127     {
11128         UINT x, y;
11129         D3DCOLOR color;
11130     }
11131     expected_colors[] =
11132     {
11133         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11134         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11135         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11136         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11137         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11138         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11139         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11140         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11141     };
11142
11143     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11144     IDirect3DPixelShader9 *ps;
11145     IDirect3D9 *d3d9;
11146     D3DCAPS9 caps;
11147     HRESULT hr;
11148     UINT i;
11149
11150     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11151     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11152     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11153     {
11154         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11155         return;
11156     }
11157
11158     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11159     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11160     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11161     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11162     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11163     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11164
11165     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11166             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11167     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11168     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11169     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11170
11171     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11172     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11173     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11174     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11176     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11177     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11178     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11179     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11180     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11181
11182     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11183     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11184     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11185     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11186     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11187     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11188     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11189     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11190     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11191     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11192
11193     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11194     {
11195         D3DFORMAT format = formats[i].format;
11196         IDirect3DTexture9 *texture;
11197         IDirect3DSurface9 *ds;
11198         unsigned int j;
11199
11200         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11201                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11202         if (FAILED(hr)) continue;
11203
11204         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11205                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11206         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11207
11208         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11209         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11210
11211         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11212         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11213
11214         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11215         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11216
11217         IDirect3DDevice9_SetPixelShader(device, NULL);
11218         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11219
11220         /* Setup the depth/stencil surface. */
11221         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11222         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11223
11224         hr = IDirect3DDevice9_BeginScene(device);
11225         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11226         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11227         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11228         hr = IDirect3DDevice9_EndScene(device);
11229         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11230
11231         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11232         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11233         IDirect3DSurface9_Release(ds);
11234
11235         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11236         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11237
11238         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11239         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11240
11241         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11242         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11243
11244         /* Do the actual shadow mapping. */
11245         hr = IDirect3DDevice9_BeginScene(device);
11246         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11247         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11248         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11249         hr = IDirect3DDevice9_EndScene(device);
11250         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11251
11252         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11253         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11254         IDirect3DTexture9_Release(texture);
11255
11256         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11257         {
11258             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11259             ok(color_match(color, expected_colors[j].color, 0),
11260                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11261                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11262                     formats[i].name, color);
11263         }
11264
11265         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11266         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11267     }
11268
11269     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11270     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11271     IDirect3DPixelShader9_Release(ps);
11272
11273     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11274     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11275     IDirect3DSurface9_Release(original_ds);
11276
11277     IDirect3DSurface9_Release(original_rt);
11278     IDirect3DSurface9_Release(rt);
11279
11280     IDirect3D9_Release(d3d9);
11281 }
11282
11283 START_TEST(visual)
11284 {
11285     IDirect3DDevice9 *device_ptr;
11286     D3DCAPS9 caps;
11287     HRESULT hr;
11288     DWORD color;
11289
11290     d3d9_handle = LoadLibraryA("d3d9.dll");
11291     if (!d3d9_handle)
11292     {
11293         skip("Could not load d3d9.dll\n");
11294         return;
11295     }
11296
11297     device_ptr = init_d3d9();
11298     if (!device_ptr)
11299     {
11300         skip("Creating the device failed\n");
11301         return;
11302     }
11303
11304     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11305
11306     /* Check for the reliability of the returned data */
11307     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11308     if(FAILED(hr))
11309     {
11310         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11311         goto cleanup;
11312     }
11313
11314     color = getPixelColor(device_ptr, 1, 1);
11315     if(color !=0x00ff0000)
11316     {
11317         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11318         goto cleanup;
11319     }
11320     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11321
11322     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11323     if(FAILED(hr))
11324     {
11325         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11326         goto cleanup;
11327     }
11328
11329     color = getPixelColor(device_ptr, 639, 479);
11330     if(color != 0x0000ddee)
11331     {
11332         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11333         goto cleanup;
11334     }
11335     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11336
11337     /* Now execute the real tests */
11338     depth_clamp_test(device_ptr);
11339     stretchrect_test(device_ptr);
11340     lighting_test(device_ptr);
11341     clear_test(device_ptr);
11342     color_fill_test(device_ptr);
11343     fog_test(device_ptr);
11344     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11345     {
11346         test_cube_wrap(device_ptr);
11347     } else {
11348         skip("No cube texture support\n");
11349     }
11350     z_range_test(device_ptr);
11351     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11352     {
11353         maxmip_test(device_ptr);
11354     }
11355     else
11356     {
11357         skip("No mipmap support\n");
11358     }
11359     offscreen_test(device_ptr);
11360     alpha_test(device_ptr);
11361     shademode_test(device_ptr);
11362     srgbtexture_test(device_ptr);
11363     release_buffer_test(device_ptr);
11364     float_texture_test(device_ptr);
11365     g16r16_texture_test(device_ptr);
11366     pixelshader_blending_test(device_ptr);
11367     texture_transform_flags_test(device_ptr);
11368     autogen_mipmap_test(device_ptr);
11369     fixed_function_decl_test(device_ptr);
11370     conditional_np2_repeat_test(device_ptr);
11371     fixed_function_bumpmap_test(device_ptr);
11372     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11373         stencil_cull_test(device_ptr);
11374     } else {
11375         skip("No two sided stencil support\n");
11376     }
11377     pointsize_test(device_ptr);
11378     tssargtemp_test(device_ptr);
11379     np2_stretch_rect_test(device_ptr);
11380     yuv_color_test(device_ptr);
11381     zwriteenable_test(device_ptr);
11382     alphatest_test(device_ptr);
11383     viewport_test(device_ptr);
11384
11385     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11386     {
11387         test_constant_clamp_vs(device_ptr);
11388         test_compare_instructions(device_ptr);
11389     }
11390     else skip("No vs_1_1 support\n");
11391
11392     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11393     {
11394         test_mova(device_ptr);
11395         loop_index_test(device_ptr);
11396         sincos_test(device_ptr);
11397         sgn_test(device_ptr);
11398         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11399             test_vshader_input(device_ptr);
11400             test_vshader_float16(device_ptr);
11401             stream_test(device_ptr);
11402         } else {
11403             skip("No vs_3_0 support\n");
11404         }
11405     }
11406     else skip("No vs_2_0 support\n");
11407
11408     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11409     {
11410         fog_with_shader_test(device_ptr);
11411         fog_srgbwrite_test(device_ptr);
11412     }
11413     else skip("No vs_1_1 and ps_1_1 support\n");
11414
11415     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11416     {
11417         texbem_test(device_ptr);
11418         texdepth_test(device_ptr);
11419         texkill_test(device_ptr);
11420         x8l8v8u8_test(device_ptr);
11421         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11422             constant_clamp_ps_test(device_ptr);
11423             cnd_test(device_ptr);
11424             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11425                 dp2add_ps_test(device_ptr);
11426                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
11427                     nested_loop_test(device_ptr);
11428                     fixed_function_varying_test(device_ptr);
11429                     vFace_register_test(device_ptr);
11430                     vpos_register_test(device_ptr);
11431                     multiple_rendertargets_test(device_ptr);
11432                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11433                         vshader_version_varying_test(device_ptr);
11434                         pshader_version_varying_test(device_ptr);
11435                     } else {
11436                         skip("No vs_3_0 support\n");
11437                     }
11438                 } else {
11439                     skip("No ps_3_0 support\n");
11440                 }
11441             } else {
11442                 skip("No ps_2_0 support\n");
11443             }
11444         }
11445     }
11446     else skip("No ps_1_1 support\n");
11447
11448     texop_test(device_ptr);
11449     texop_range_test(device_ptr);
11450     alphareplicate_test(device_ptr);
11451     dp3_alpha_test(device_ptr);
11452     depth_buffer_test(device_ptr);
11453     shadow_test(device_ptr);
11454
11455 cleanup:
11456     if(device_ptr) {
11457         D3DPRESENT_PARAMETERS present_parameters;
11458         IDirect3DSwapChain9 *swapchain;
11459         ULONG ref;
11460
11461         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11462         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11463         IDirect3DSwapChain9_Release(swapchain);
11464         ref = IDirect3DDevice9_Release(device_ptr);
11465         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11466         DestroyWindow(present_parameters.hDeviceWindow);
11467     }
11468 }