shlwapi/tests: ChrCmpI* is not present on Win95B (winetestbot).
[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     trace("viewport: X %u, Y %u, W %u, H %u, MinZ %.8e, MaxZ %.8e.\n",
499             old_vp.X, old_vp.Y, old_vp.Width, old_vp.Height, old_vp.MinZ, old_vp.MaxZ);
500
501     vp.X = 160;
502     vp.Y = 120;
503     vp.Width = 160;
504     vp.Height = 120;
505     vp.MinZ = 0.0;
506     vp.MaxZ = 1.0;
507     hr = IDirect3DDevice9_SetViewport(device, &vp);
508     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
509     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
510     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
511
512     vp.X = 320;
513     vp.Y = 240;
514     vp.Width = 320;
515     vp.Height = 240;
516     vp.MinZ = 0.0;
517     vp.MaxZ = 1.0;
518     hr = IDirect3DDevice9_SetViewport(device, &vp);
519     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
520     rect[0].x1 = 160;
521     rect[0].y1 = 120;
522     rect[0].x2 = 480;
523     rect[0].y2 = 360;
524     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
525     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
526
527     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
528     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
529
530     color = getPixelColor(device, 158, 118);
531     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
532     color = getPixelColor(device, 162, 118);
533     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
534     color = getPixelColor(device, 158, 122);
535     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
536     color = getPixelColor(device, 162, 122);
537     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
538
539     color = getPixelColor(device, 318, 238);
540     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
541     color = getPixelColor(device, 322, 238);
542     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
543     color = getPixelColor(device, 318, 242);
544     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
545     color = getPixelColor(device, 322, 242);
546     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
547
548     color = getPixelColor(device, 478, 358);
549     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
550     color = getPixelColor(device, 482, 358);
551     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
552     color = getPixelColor(device, 478, 362);
553     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
554     color = getPixelColor(device, 482, 362);
555     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
556
557     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
558
559     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
560     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
561
562     scissor.left = 160;
563     scissor.right = 480;
564     scissor.top = 120;
565     scissor.bottom = 360;
566     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
567     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
568     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
569     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
570
571     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
572     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
573     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
574     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
575
576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
577     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
578
579     color = getPixelColor(device, 158, 118);
580     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
581     color = getPixelColor(device, 162, 118);
582     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
583     color = getPixelColor(device, 158, 122);
584     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
585     color = getPixelColor(device, 162, 122);
586     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
587
588     color = getPixelColor(device, 158, 358);
589     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
590     color = getPixelColor(device, 162, 358);
591     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
592     color = getPixelColor(device, 158, 358);
593     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
594     color = getPixelColor(device, 162, 362);
595     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
596
597     color = getPixelColor(device, 478, 118);
598     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
599     color = getPixelColor(device, 478, 122);
600     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
601     color = getPixelColor(device, 482, 122);
602     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
603     color = getPixelColor(device, 482, 358);
604     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
605
606     color = getPixelColor(device, 478, 358);
607     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
608     color = getPixelColor(device, 478, 362);
609     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
610     color = getPixelColor(device, 482, 358);
611     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
612     color = getPixelColor(device, 482, 362);
613     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
614
615     color = getPixelColor(device, 318, 238);
616     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
617     color = getPixelColor(device, 318, 242);
618     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
619     color = getPixelColor(device, 322, 238);
620     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
621     color = getPixelColor(device, 322, 242);
622     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
623
624     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
625
626     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
627     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
628     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
629     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
632     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
633
634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
635     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
636
637     /* Colorwriteenable does not affect the clear */
638     color = getPixelColor(device, 320, 240);
639     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
640
641     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
642 }
643
644 typedef struct {
645     float in[4];
646     DWORD out;
647 } test_data_t;
648
649 /*
650  *  c7      mova    ARGB            mov     ARGB
651  * -2.4     -2      0x00ffff00      -3      0x00ff0000
652  * -1.6     -2      0x00ffff00      -2      0x00ffff00
653  * -0.4      0      0x0000ffff      -1      0x0000ff00
654  *  0.4      0      0x0000ffff       0      0x0000ffff
655  *  1.6      2      0x00ff00ff       1      0x000000ff
656  *  2.4      2      0x00ff00ff       2      0x00ff00ff
657  */
658 static void test_mova(IDirect3DDevice9 *device)
659 {
660     static const DWORD mova_test[] = {
661         0xfffe0200,                                                             /* vs_2_0                       */
662         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
663         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
664         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
665         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
666         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
667         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
668         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
669         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
670         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
671         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
672         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
673         0x0000ffff                                                              /* END                          */
674     };
675     static const DWORD mov_test[] = {
676         0xfffe0101,                                                             /* vs_1_1                       */
677         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
678         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
679         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
680         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
681         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
682         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
683         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
684         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
685         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
686         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
687         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
688         0x0000ffff                                                              /* END                          */
689     };
690
691     static const test_data_t test_data[2][6] = {
692         {
693             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
694             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
695             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
696             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
697             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
698             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
699         },
700         {
701             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
702             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
703             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
704             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
705             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
706             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
707         }
708     };
709
710     static const float quad[][3] = {
711         {-1.0f, -1.0f, 0.0f},
712         {-1.0f,  1.0f, 0.0f},
713         { 1.0f, -1.0f, 0.0f},
714         { 1.0f,  1.0f, 0.0f},
715     };
716
717     static const D3DVERTEXELEMENT9 decl_elements[] = {
718         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
719         D3DDECL_END()
720     };
721
722     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
723     IDirect3DVertexShader9 *mova_shader = NULL;
724     IDirect3DVertexShader9 *mov_shader = NULL;
725     HRESULT hr;
726     UINT i, j;
727
728     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
729     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
730     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
731     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
732     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
733     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
734     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
735     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
736
737     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
738     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
739     for(j = 0; j < 2; ++j)
740     {
741         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
742         {
743             DWORD color;
744
745             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
746             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
747
748             hr = IDirect3DDevice9_BeginScene(device);
749             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
750
751             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
752             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
753
754             hr = IDirect3DDevice9_EndScene(device);
755             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
756
757             color = getPixelColor(device, 320, 240);
758             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
759                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
760
761             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
762             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
763
764             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
765             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
766         }
767         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
768         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
769     }
770
771     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
772     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
773
774     IDirect3DVertexDeclaration9_Release(vertex_declaration);
775     IDirect3DVertexShader9_Release(mova_shader);
776     IDirect3DVertexShader9_Release(mov_shader);
777 }
778
779 struct sVertex {
780     float x, y, z;
781     DWORD diffuse;
782     DWORD specular;
783 };
784
785 struct sVertexT {
786     float x, y, z, rhw;
787     DWORD diffuse;
788     DWORD specular;
789 };
790
791 static void fog_test(IDirect3DDevice9 *device)
792 {
793     HRESULT hr;
794     D3DCOLOR color;
795     float start = 0.0f, end = 1.0f;
796     D3DCAPS9 caps;
797     int i;
798
799     /* Gets full z based fog with linear fog, no fog with specular color */
800     struct sVertex unstransformed_1[] = {
801         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
802         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
803         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
804         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
805     };
806     /* Ok, I am too lazy to deal with transform matrices */
807     struct sVertex unstransformed_2[] = {
808         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
809         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
810         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
811         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
812     };
813     /* Untransformed ones. Give them a different diffuse color to make the test look
814      * nicer. It also makes making sure that they are drawn correctly easier.
815      */
816     struct sVertexT transformed_1[] = {
817         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
818         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
819         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
820         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
821     };
822     struct sVertexT transformed_2[] = {
823         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
824         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
825         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
826         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
827     };
828     struct vertex rev_fog_quads[] = {
829        {-1.0,   -1.0,   0.1,    0x000000ff},
830        {-1.0,    0.0,   0.1,    0x000000ff},
831        { 0.0,    0.0,   0.1,    0x000000ff},
832        { 0.0,   -1.0,   0.1,    0x000000ff},
833
834        { 0.0,   -1.0,   0.9,    0x000000ff},
835        { 0.0,    0.0,   0.9,    0x000000ff},
836        { 1.0,    0.0,   0.9,    0x000000ff},
837        { 1.0,   -1.0,   0.9,    0x000000ff},
838
839        { 0.0,    0.0,   0.4,    0x000000ff},
840        { 0.0,    1.0,   0.4,    0x000000ff},
841        { 1.0,    1.0,   0.4,    0x000000ff},
842        { 1.0,    0.0,   0.4,    0x000000ff},
843
844        {-1.0,    0.0,   0.7,    0x000000ff},
845        {-1.0,    1.0,   0.7,    0x000000ff},
846        { 0.0,    1.0,   0.7,    0x000000ff},
847        { 0.0,    0.0,   0.7,    0x000000ff},
848     };
849     WORD Indices[] = {0, 1, 2, 2, 3, 0};
850
851     memset(&caps, 0, sizeof(caps));
852     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
853     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
854     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
855     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
856
857     /* Setup initial states: No lighting, fog on, fog color */
858     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
859     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
860     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
861     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
863     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
864
865     /* First test: Both table fog and vertex fog off */
866     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
867     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
868     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
869     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
870
871     /* Start = 0, end = 1. Should be default, but set them */
872     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
873     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
874     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
875     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
876
877     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
878     {
879         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
880         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
881         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
882         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
883                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
884                                                      sizeof(unstransformed_1[0]));
885         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
886
887         /* That makes it use the Z value */
888         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
889         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
890         /* Untransformed, vertex fog != none (or table fog != none):
891          * Use the Z value as input into the equation
892          */
893         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
894                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
895                                                      sizeof(unstransformed_1[0]));
896         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
897
898         /* transformed verts */
899         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
900         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
901         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
902         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
903                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
904                                                      sizeof(transformed_1[0]));
905         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
906
907         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
908         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
909         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
910          * equation
911          */
912         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
913                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
914                                                      sizeof(transformed_2[0]));
915         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
916
917         hr = IDirect3DDevice9_EndScene(device);
918         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
919     }
920     else
921     {
922         ok(FALSE, "BeginScene failed\n");
923     }
924
925     color = getPixelColor(device, 160, 360);
926     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
927     color = getPixelColor(device, 160, 120);
928     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
929     color = getPixelColor(device, 480, 120);
930     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
931     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
932     {
933         color = getPixelColor(device, 480, 360);
934         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
935     }
936     else
937     {
938         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
939          * The settings above result in no fogging with vertex fog
940          */
941         color = getPixelColor(device, 480, 120);
942         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
943         trace("Info: Table fog not supported by this device\n");
944     }
945     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
946
947     /* Now test the special case fogstart == fogend */
948     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
949     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
950
951     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
952     {
953         start = 512;
954         end = 512;
955         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
956         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
957         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
958         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
959
960         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
961         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
962         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
963         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
964         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
965         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
966
967         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
968          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
969          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
970          * The third transformed quad remains unfogged because the fogcoords are read from the specular
971          * color and has fixed fogstart and fogend.
972          */
973         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
975                 sizeof(unstransformed_1[0]));
976         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
977         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
978                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
979                 sizeof(unstransformed_1[0]));
980         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
981
982         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
983         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
984         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
985         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
986                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
987                 sizeof(transformed_1[0]));
988         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
989
990         hr = IDirect3DDevice9_EndScene(device);
991         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
992     }
993     else
994     {
995         ok(FALSE, "BeginScene failed\n");
996     }
997     color = getPixelColor(device, 160, 360);
998     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
999     color = getPixelColor(device, 160, 120);
1000     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1001     color = getPixelColor(device, 480, 120);
1002     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1003     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1004
1005     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1006      * but without shaders it seems to work everywhere
1007      */
1008     end = 0.2;
1009     start = 0.8;
1010     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1011     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1012     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1013     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1014     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1015     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1016
1017     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1018      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1019      * so skip this for now
1020      */
1021     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1022         const char *mode = (i ? "table" : "vertex");
1023         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1024         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1025         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1026         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1027         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1028         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1029         hr = IDirect3DDevice9_BeginScene(device);
1030         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1031         if(SUCCEEDED(hr)) {
1032             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1033                                 4,  5,  6,  6,  7, 4,
1034                                 8,  9, 10, 10, 11, 8,
1035                             12, 13, 14, 14, 15, 12};
1036
1037             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1038                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1039                     sizeof(rev_fog_quads[0]));
1040             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1041
1042             hr = IDirect3DDevice9_EndScene(device);
1043             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1044         }
1045         color = getPixelColor(device, 160, 360);
1046         ok(color_match(color, 0x0000ff00, 1),
1047                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1048
1049         color = getPixelColor(device, 160, 120);
1050         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1051                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1052
1053         color = getPixelColor(device, 480, 120);
1054         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1055                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1056
1057         color = getPixelColor(device, 480, 360);
1058         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1059
1060         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1061
1062         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1063             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1064             break;
1065         }
1066     }
1067     /* Turn off the fog master switch to avoid confusing other tests */
1068     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1069     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1070     start = 0.0;
1071     end = 1.0;
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_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1078     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1079     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1080 }
1081
1082 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1083  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1084  * regardless of the actual addressing mode set. */
1085 static void test_cube_wrap(IDirect3DDevice9 *device)
1086 {
1087     static const float quad[][6] = {
1088         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1089         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1090         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1091         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1092     };
1093
1094     static const D3DVERTEXELEMENT9 decl_elements[] = {
1095         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1096         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1097         D3DDECL_END()
1098     };
1099
1100     static const struct {
1101         D3DTEXTUREADDRESS mode;
1102         const char *name;
1103     } address_modes[] = {
1104         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1105         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1106         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1107         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1108         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1109     };
1110
1111     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1112     IDirect3DCubeTexture9 *texture = NULL;
1113     IDirect3DSurface9 *surface = NULL;
1114     D3DLOCKED_RECT locked_rect;
1115     HRESULT hr;
1116     UINT x;
1117     INT y, face;
1118
1119     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1120     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1121     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1122     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1123
1124     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1125             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1126     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1127
1128     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1129     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1130
1131     for (y = 0; y < 128; ++y)
1132     {
1133         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1134         for (x = 0; x < 64; ++x)
1135         {
1136             *ptr++ = 0xffff0000;
1137         }
1138         for (x = 64; x < 128; ++x)
1139         {
1140             *ptr++ = 0xff0000ff;
1141         }
1142     }
1143
1144     hr = IDirect3DSurface9_UnlockRect(surface);
1145     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1146
1147     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1148             D3DPOOL_DEFAULT, &texture, NULL);
1149     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1150
1151     /* Create cube faces */
1152     for (face = 0; face < 6; ++face)
1153     {
1154         IDirect3DSurface9 *face_surface = NULL;
1155
1156         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1157         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1158
1159         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1160         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1161
1162         IDirect3DSurface9_Release(face_surface);
1163     }
1164
1165     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1166     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1167
1168     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1169     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1170     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1171     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1172     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1173     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1174
1175     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1176     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1177
1178     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1179     {
1180         DWORD color;
1181
1182         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1183         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1184         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1185         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1186
1187         hr = IDirect3DDevice9_BeginScene(device);
1188         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1189
1190         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1191         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1192
1193         hr = IDirect3DDevice9_EndScene(device);
1194         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1195
1196         /* Due to the nature of this test, we sample essentially at the edge
1197          * between two faces. Because of this it's undefined from which face
1198          * the driver will sample. Fortunately that's not important for this
1199          * test, since all we care about is that it doesn't sample from the
1200          * other side of the surface or from the border. */
1201         color = getPixelColor(device, 320, 240);
1202         ok(color == 0x00ff0000 || color == 0x000000ff,
1203                 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1204                 color, address_modes[x].name);
1205
1206         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1207         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1208
1209         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1210         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1211     }
1212
1213     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1214     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1215
1216     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1217     IDirect3DCubeTexture9_Release(texture);
1218     IDirect3DSurface9_Release(surface);
1219 }
1220
1221 static void offscreen_test(IDirect3DDevice9 *device)
1222 {
1223     HRESULT hr;
1224     IDirect3DTexture9 *offscreenTexture = NULL;
1225     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1226     DWORD color;
1227
1228     static const float quad[][5] = {
1229         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1230         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1231         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1232         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1233     };
1234
1235     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1236     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1237
1238     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1239     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1240     if(!offscreenTexture) {
1241         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1242         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1243         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1244         if(!offscreenTexture) {
1245             skip("Cannot create an offscreen render target\n");
1246             goto out;
1247         }
1248     }
1249
1250     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1251     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1252     if(!backbuffer) {
1253         goto out;
1254     }
1255
1256     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1257     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1258     if(!offscreen) {
1259         goto out;
1260     }
1261
1262     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1263     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1264
1265     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1266     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1267     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1268     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1269     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1270     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1271     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1272     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1273     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1274     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1275
1276     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1277         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1278         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1279         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1280         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1281
1282         /* Draw without textures - Should result in a white quad */
1283         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1284         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1285
1286         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1287         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1288         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1289         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1290
1291         /* This time with the texture */
1292         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1293         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1294
1295         IDirect3DDevice9_EndScene(device);
1296     }
1297
1298     /* Center quad - should be white */
1299     color = getPixelColor(device, 320, 240);
1300     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1301     /* Some quad in the cleared part of the texture */
1302     color = getPixelColor(device, 170, 240);
1303     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1304     /* Part of the originally cleared back buffer */
1305     color = getPixelColor(device, 10, 10);
1306     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1307     if(0) {
1308         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1309          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1310          * the offscreen rendering mode this test would succeed or fail
1311          */
1312         color = getPixelColor(device, 10, 470);
1313         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1314     }
1315
1316     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1317
1318 out:
1319     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1320     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1321
1322     /* restore things */
1323     if(backbuffer) {
1324         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1325         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1326         IDirect3DSurface9_Release(backbuffer);
1327     }
1328     if(offscreenTexture) {
1329         IDirect3DTexture9_Release(offscreenTexture);
1330     }
1331     if(offscreen) {
1332         IDirect3DSurface9_Release(offscreen);
1333     }
1334 }
1335
1336 /* This test tests fog in combination with shaders.
1337  * What's tested: linear fog (vertex and table) with pixel shader
1338  *                linear table fog with non foggy vertex shader
1339  *                vertex fog with foggy vertex shader, non-linear
1340  *                fog with shader, non-linear fog with foggy shader,
1341  *                linear table fog with foggy shader
1342  */
1343 static void fog_with_shader_test(IDirect3DDevice9 *device)
1344 {
1345     HRESULT hr;
1346     DWORD color;
1347     union {
1348         float f;
1349         DWORD i;
1350     } start, end;
1351     unsigned int i, j;
1352
1353     /* basic vertex shader without fog computation ("non foggy") */
1354     static const DWORD vertex_shader_code1[] = {
1355         0xfffe0101,                                                             /* vs_1_1                       */
1356         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1357         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1358         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1359         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1360         0x0000ffff
1361     };
1362     /* basic vertex shader with reversed fog computation ("foggy") */
1363     static const DWORD vertex_shader_code2[] = {
1364         0xfffe0101,                                                             /* vs_1_1                        */
1365         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1366         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1367         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1368         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1369         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1370         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1371         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1372         0x0000ffff
1373     };
1374     /* basic pixel shader */
1375     static const DWORD pixel_shader_code[] = {
1376         0xffff0101,                                                             /* ps_1_1     */
1377         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1378         0x0000ffff
1379     };
1380
1381     static struct vertex quad[] = {
1382         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1383         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1384         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1385         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1386     };
1387
1388     static const D3DVERTEXELEMENT9 decl_elements[] = {
1389         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1390         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1391         D3DDECL_END()
1392     };
1393
1394     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1395     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1396     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1397
1398     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1399     static const struct test_data_t {
1400         int vshader;
1401         int pshader;
1402         D3DFOGMODE vfog;
1403         D3DFOGMODE tfog;
1404         unsigned int color[11];
1405     } test_data[] = {
1406         /* only pixel shader: */
1407         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1408         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1410         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1411         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1412         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1413         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1414         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1415         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1416         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1417         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1418         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1419         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1420         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1421         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1422
1423         /* vertex shader */
1424         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1425         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1426          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1427         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1428         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1429         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1430         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1431         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1432         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1433
1434         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1435         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1436         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1437         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1438         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1439         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1440
1441         /* vertex shader and pixel shader */
1442         /* The next 4 tests would read the fog coord output, but it isn't available.
1443          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1444          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1445          * These tests should be disabled if some other hardware behaves differently
1446          */
1447         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1448         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1449         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1450         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1451         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1452         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1453         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1454         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1455         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1456         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1457         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1458         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1459
1460         /* These use the Z coordinate with linear table fog */
1461         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1462         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1463         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1464         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1465         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1466         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1467         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1468         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1469         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1470         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1471         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1472         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1473
1474         /* Non-linear table fog without fog coord */
1475         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1476         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1477         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1478         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1479         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1480         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1481
1482 #if 0  /* FIXME: these fail on GeForce 8500 */
1483         /* foggy vertex shader */
1484         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1485         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1488         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1491         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1494         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1495          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1496 #endif
1497
1498         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1499          * all using the fixed fog-coord linear fog
1500          */
1501         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1502         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1503          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1504         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1505         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1506          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1507         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1508         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1509          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1510         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1511         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1512          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1513
1514         /* These use table fog. Here the shader-provided fog coordinate is
1515          * ignored and the z coordinate used instead
1516          */
1517         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1518         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1519         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1520         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1521         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1522         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1523         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1524         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1525         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1526     };
1527
1528     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1529     start.f=0.1f;
1530     end.f=0.9f;
1531
1532     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1533     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1534     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1535     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1536     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1537     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1538     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1539     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1540
1541     /* Setup initial states: No lighting, fog on, fog color */
1542     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1543     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1544     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1545     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1546     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1547     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1548     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1549     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1550
1551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1552     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1553     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1554     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1555
1556     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1557     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1558     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1559     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1560     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1561
1562     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1563     {
1564         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1565         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1566         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1567         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1568         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1569         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1570         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1571         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1572
1573         for(j=0; j < 11; j++)
1574         {
1575             /* Don't use the whole zrange to prevent rounding errors */
1576             quad[0].z = 0.001f + (float)j / 10.02f;
1577             quad[1].z = 0.001f + (float)j / 10.02f;
1578             quad[2].z = 0.001f + (float)j / 10.02f;
1579             quad[3].z = 0.001f + (float)j / 10.02f;
1580
1581             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1582             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1583
1584             hr = IDirect3DDevice9_BeginScene(device);
1585             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1586
1587             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1588             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1589
1590             hr = IDirect3DDevice9_EndScene(device);
1591             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1592
1593             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1594             color = getPixelColor(device, 128, 240);
1595             ok(color_match(color, test_data[i].color[j], 13),
1596                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1597                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1598
1599             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1600         }
1601     }
1602
1603     /* reset states */
1604     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1605     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1606     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1607     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1608     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1609     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1610     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1611     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1612
1613     IDirect3DVertexShader9_Release(vertex_shader[1]);
1614     IDirect3DVertexShader9_Release(vertex_shader[2]);
1615     IDirect3DPixelShader9_Release(pixel_shader[1]);
1616     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1617 }
1618
1619 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1620     unsigned int i, x, y;
1621     HRESULT hr;
1622     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1623     D3DLOCKED_RECT locked_rect;
1624
1625     /* Generate the textures */
1626     for(i=0; i<2; i++)
1627     {
1628         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1629                                             D3DPOOL_MANAGED, &texture[i], NULL);
1630         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1631
1632         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1633         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1634         for (y = 0; y < 128; ++y)
1635         {
1636             if(i)
1637             { /* Set up black texture with 2x2 texel white spot in the middle */
1638                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1639                 for (x = 0; x < 128; ++x)
1640                 {
1641                     if(y>62 && y<66 && x>62 && x<66)
1642                         *ptr++ = 0xffffffff;
1643                     else
1644                         *ptr++ = 0xff000000;
1645                 }
1646             }
1647             else
1648             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1649                * (if multiplied with bumpenvmat)
1650               */
1651                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1652                 for (x = 0; x < 128; ++x)
1653                 {
1654                     if(abs(x-64)>abs(y-64))
1655                     {
1656                         if(x < 64)
1657                             *ptr++ = 0xc000;
1658                         else
1659                             *ptr++ = 0x4000;
1660                     }
1661                     else
1662                     {
1663                         if(y < 64)
1664                             *ptr++ = 0x0040;
1665                         else
1666                             *ptr++ = 0x00c0;
1667                     }
1668                 }
1669             }
1670         }
1671         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1672         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1673
1674         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1675         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1676
1677         /* Disable texture filtering */
1678         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1679         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1680         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1681         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1682
1683         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1684         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1685         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1686         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1687     }
1688 }
1689
1690 /* test the behavior of the texbem instruction
1691  * with normal 2D and projective 2D textures
1692  */
1693 static void texbem_test(IDirect3DDevice9 *device)
1694 {
1695     HRESULT hr;
1696     DWORD color;
1697     int i;
1698
1699     static const DWORD pixel_shader_code[] = {
1700         0xffff0101,                         /* ps_1_1*/
1701         0x00000042, 0xb00f0000,             /* tex t0*/
1702         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1703         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1704         0x0000ffff
1705     };
1706     static const DWORD double_texbem_code[] =  {
1707         0xffff0103,                                         /* ps_1_3           */
1708         0x00000042, 0xb00f0000,                             /* tex t0           */
1709         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1710         0x00000042, 0xb00f0002,                             /* tex t2           */
1711         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1712         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1713         0x0000ffff                                          /* end              */
1714     };
1715
1716
1717     static const float quad[][7] = {
1718         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1719         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1720         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1721         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1722     };
1723     static const float quad_proj[][9] = {
1724         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1725         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1726         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1727         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1728     };
1729
1730     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1731         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1732         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1733         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1734         D3DDECL_END()
1735     },{
1736         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1737         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1738         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1739         D3DDECL_END()
1740     } };
1741
1742     /* use asymmetric matrix to test loading */
1743     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1744
1745     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1746     IDirect3DPixelShader9       *pixel_shader       = NULL;
1747     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1748     D3DLOCKED_RECT locked_rect;
1749
1750     generate_bumpmap_textures(device);
1751
1752     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1753     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1754     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1755     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1756     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1757
1758     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1759     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1760
1761     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1762     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1763
1764     for(i=0; i<2; i++)
1765     {
1766         if(i)
1767         {
1768             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1769             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1770         }
1771
1772         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1773         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1774         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1775         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1776
1777         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1778         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1779         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1780         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1781
1782         hr = IDirect3DDevice9_BeginScene(device);
1783         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1784
1785         if(!i)
1786             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1787         else
1788             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1789         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1790
1791         hr = IDirect3DDevice9_EndScene(device);
1792         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1793
1794         color = getPixelColor(device, 320-32, 240);
1795         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1796         color = getPixelColor(device, 320+32, 240);
1797         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1798         color = getPixelColor(device, 320, 240-32);
1799         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1800         color = getPixelColor(device, 320, 240+32);
1801         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1802
1803         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1804         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1805
1806         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1807         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1808         IDirect3DPixelShader9_Release(pixel_shader);
1809
1810         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1811         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1812         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1813     }
1814
1815     /* clean up */
1816     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1817     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1818
1819     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1820     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1821
1822     for(i=0; i<2; i++)
1823     {
1824         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1825         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1826         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1827         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1828         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1829         IDirect3DTexture9_Release(texture);
1830     }
1831
1832     /* Test double texbem */
1833     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1834     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1835     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1836     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1837     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1838     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1839     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1840     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1841
1842     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1843     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1844     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1845     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1846
1847     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1848     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1849
1850     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1851     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1852     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1853     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1854     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1855     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1856
1857     {
1858         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1859 #define tex  0x00ff0000
1860 #define tex1 0x0000ff00
1861 #define origin 0x000000ff
1862         static const DWORD pixel_data[] = {
1863             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1864             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1865             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1866             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1867             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1868             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1869             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1870             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1871         };
1872 #undef tex1
1873 #undef tex2
1874 #undef origin
1875
1876         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1877         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1878         for(i = 0; i < 8; i++) {
1879             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1880         }
1881         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1882         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1883     }
1884
1885     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1886     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1887     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1888     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1889     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1890     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1891     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1892     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1893     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1894     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1895     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1896     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1897
1898     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1899     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1900     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1901     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1902     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1903     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1904     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1905     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1906     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1907     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1908
1909     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
1910     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
1911     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1912     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1913     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1914     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1915     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1916     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1917     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1918     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1919
1920     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1921     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1922     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1923     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1924     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1925     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1926     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1927     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1928     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1929     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1930     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1931     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1932     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1933     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1934     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1935     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
1936
1937     hr = IDirect3DDevice9_BeginScene(device);
1938     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1939     if(SUCCEEDED(hr)) {
1940         static const float double_quad[] = {
1941             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1942              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1943             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1944              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
1945         };
1946
1947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1948         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1949         hr = IDirect3DDevice9_EndScene(device);
1950         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1951     }
1952     color = getPixelColor(device, 320, 240);
1953     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1954
1955     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1956     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1957     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1958     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1959     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1960     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1961     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1962     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1963     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1964     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1965
1966     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1967     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1968
1969     IDirect3DPixelShader9_Release(pixel_shader);
1970     IDirect3DTexture9_Release(texture);
1971     IDirect3DTexture9_Release(texture1);
1972     IDirect3DTexture9_Release(texture2);
1973 }
1974
1975 static void z_range_test(IDirect3DDevice9 *device)
1976 {
1977     const struct vertex quad[] =
1978     {
1979         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
1980         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
1981         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
1982         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
1983     };
1984     const struct vertex quad2[] =
1985     {
1986         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
1987         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
1988         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
1989         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
1990     };
1991
1992     const struct tvertex quad3[] =
1993     {
1994         {    0,   240,   1.1f,  1.0,                    0xffffff00},
1995         {    0,   480,   1.1f,  1.0,                    0xffffff00},
1996         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
1997         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
1998     };
1999     const struct tvertex quad4[] =
2000     {
2001         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2002         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2003         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2004         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2005     };
2006     HRESULT hr;
2007     DWORD color;
2008     IDirect3DVertexShader9 *shader;
2009     IDirect3DVertexDeclaration9 *decl;
2010     D3DCAPS9 caps;
2011     const DWORD shader_code[] = {
2012         0xfffe0101,                                     /* vs_1_1           */
2013         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2014         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2015         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2016         0x0000ffff                                      /* end              */
2017     };
2018     static const D3DVERTEXELEMENT9 decl_elements[] = {
2019         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2020         D3DDECL_END()
2021     };
2022     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2023      * then call Present. Then clear the color buffer to make sure it has some defined content
2024      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2025      * by the depth value.
2026      */
2027     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2028     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2029     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2030     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2031     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2032     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2033
2034     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2035     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2036     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2037     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2038     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2039     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2040     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2041     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2042     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2043     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2044
2045     hr = IDirect3DDevice9_BeginScene(device);
2046     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2047     if(hr == D3D_OK)
2048     {
2049         /* Test the untransformed vertex path */
2050         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2051         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2052         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2053         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2054         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2055         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2056
2057         /* Test the transformed vertex path */
2058         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2059         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2060
2061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2062         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2063         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2064         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2065         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2066         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2067
2068         hr = IDirect3DDevice9_EndScene(device);
2069         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2070     }
2071
2072     /* Do not test the exact corner pixels, but go pretty close to them */
2073
2074     /* Clipped because z > 1.0 */
2075     color = getPixelColor(device, 28, 238);
2076     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2077     color = getPixelColor(device, 28, 241);
2078     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2079
2080     /* Not clipped, > z buffer clear value(0.75) */
2081     color = getPixelColor(device, 31, 238);
2082     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2083     color = getPixelColor(device, 31, 241);
2084     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2085     color = getPixelColor(device, 100, 238);
2086     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2087     color = getPixelColor(device, 100, 241);
2088     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2089
2090     /* Not clipped, < z buffer clear value */
2091     color = getPixelColor(device, 104, 238);
2092     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2093     color = getPixelColor(device, 104, 241);
2094     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2095     color = getPixelColor(device, 318, 238);
2096     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2097     color = getPixelColor(device, 318, 241);
2098     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2099
2100     /* Clipped because z < 0.0 */
2101     color = getPixelColor(device, 321, 238);
2102     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2103     color = getPixelColor(device, 321, 241);
2104     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2105
2106     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2107     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2108
2109     /* Test the shader path */
2110     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2111     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2112         skip("Vertex shaders not supported\n");
2113         goto out;
2114     }
2115     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2116     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2117     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2119
2120     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2121
2122     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2123     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2124     IDirect3DDevice9_SetVertexShader(device, shader);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2126
2127     hr = IDirect3DDevice9_BeginScene(device);
2128     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2129     if(hr == D3D_OK)
2130     {
2131         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2132         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2133         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2134         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2135         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2136         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2137         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2138         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2139         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2140         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2141
2142         hr = IDirect3DDevice9_EndScene(device);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2144     }
2145
2146     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2147     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2148     IDirect3DDevice9_SetVertexShader(device, NULL);
2149     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2150
2151     IDirect3DVertexDeclaration9_Release(decl);
2152     IDirect3DVertexShader9_Release(shader);
2153
2154     /* Z < 1.0 */
2155     color = getPixelColor(device, 28, 238);
2156     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2157
2158     /* 1.0 < z < 0.75 */
2159     color = getPixelColor(device, 31, 238);
2160     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2161     color = getPixelColor(device, 100, 238);
2162     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2163
2164     /* 0.75 < z < 0.0 */
2165     color = getPixelColor(device, 104, 238);
2166     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2167     color = getPixelColor(device, 318, 238);
2168     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2169
2170     /* 0.0 < z */
2171     color = getPixelColor(device, 321, 238);
2172     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2173
2174     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2175     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2176
2177     out:
2178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2179     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2180     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2181     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2182     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2183     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2184 }
2185
2186 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2187 {
2188     D3DSURFACE_DESC desc;
2189     D3DLOCKED_RECT l;
2190     HRESULT hr;
2191     unsigned int x, y;
2192     DWORD *mem;
2193
2194     memset(&desc, 0, sizeof(desc));
2195     memset(&l, 0, sizeof(l));
2196     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2197     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2198     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2199     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2200     if(FAILED(hr)) return;
2201
2202     for(y = 0; y < desc.Height; y++)
2203     {
2204         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2205         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2206         {
2207             mem[x] = color;
2208         }
2209     }
2210     hr = IDirect3DSurface9_UnlockRect(surface);
2211     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2212 }
2213
2214 /* This tests a variety of possible StretchRect() situations */
2215 static void stretchrect_test(IDirect3DDevice9 *device)
2216 {
2217     HRESULT hr;
2218     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2219     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2220     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2221     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2222     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2223     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2224     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2225     IDirect3DSurface9 *orig_rt = NULL;
2226     DWORD color;
2227
2228     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2229     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2230     if(!orig_rt) {
2231         goto out;
2232     }
2233
2234     /* Create our temporary surfaces in system memory */
2235     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2236     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2237     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2238     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2239
2240     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2241     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2242     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2243     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2244     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2245     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2246     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2247
2248     /* Create render target surfaces */
2249     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2250     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2251     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2252     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2253     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2254     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2255
2256     /* Create render target textures */
2257     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2258     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2259     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2260     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2261     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2262     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2263     if (tex_rt32) {
2264         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2265         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2266     }
2267     if (tex_rt64) {
2268         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2269         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2270     }
2271     if (tex_rt_dest64) {
2272         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2273         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2274     }
2275
2276     /* Create regular textures in D3DPOOL_DEFAULT */
2277     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2278     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2279     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2280     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2281     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2282     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2283     if (tex32) {
2284         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2285         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2286     }
2287     if (tex64) {
2288         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2289         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2290     }
2291     if (tex_dest64) {
2292         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2293         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2294     }
2295
2296     /*********************************************************************
2297      * Tests for when the source parameter is an offscreen plain surface *
2298      *********************************************************************/
2299
2300     /* Fill the offscreen 64x64 surface with green */
2301     if (surf_offscreen64)
2302         fill_surface(surf_offscreen64, 0xff00ff00);
2303
2304     /* offscreenplain ==> offscreenplain, same size */
2305     if(surf_offscreen64 && surf_offscreen_dest64) {
2306         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2307         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2308
2309         if (hr == D3D_OK) {
2310             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2311             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2312         }
2313     }
2314
2315     /* offscreenplain ==> rendertarget texture, same size */
2316     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2317         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2318         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2319
2320         /* We can't lock rendertarget textures, so copy to our temp surface first */
2321         if (hr == D3D_OK) {
2322             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2323             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2324         }
2325
2326         if (hr == D3D_OK) {
2327             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2328             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2329         }
2330     }
2331
2332     /* offscreenplain ==> rendertarget surface, same size */
2333     if(surf_offscreen64 && surf_rt_dest64) {
2334         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2335         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2336
2337         if (hr == D3D_OK) {
2338             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2339             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2340         }
2341     }
2342
2343     /* offscreenplain ==> texture, same size (should fail) */
2344     if(surf_offscreen64 && surf_tex_dest64) {
2345         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2346         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2347     }
2348
2349     /* Fill the smaller offscreen surface with red */
2350     fill_surface(surf_offscreen32, 0xffff0000);
2351
2352     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2353     if(surf_offscreen32 && surf_offscreen64) {
2354         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2355         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2356     }
2357
2358     /* offscreenplain ==> rendertarget texture, scaling */
2359     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2360         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2361         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2362
2363         /* We can't lock rendertarget textures, so copy to our temp surface first */
2364         if (hr == D3D_OK) {
2365             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2366             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2367         }
2368
2369         if (hr == D3D_OK) {
2370             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2371             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2372         }
2373     }
2374
2375     /* offscreenplain ==> rendertarget surface, scaling */
2376     if(surf_offscreen32 && surf_rt_dest64) {
2377         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2378         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2379
2380         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2381         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2382     }
2383
2384     /* offscreenplain ==> texture, scaling (should fail) */
2385     if(surf_offscreen32 && surf_tex_dest64) {
2386         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2387         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2388     }
2389
2390     /************************************************************
2391      * Tests for when the source parameter is a regular texture *
2392      ************************************************************/
2393
2394     /* Fill the surface of the regular texture with blue */
2395     if (surf_tex64 && surf_temp64) {
2396         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2397         fill_surface(surf_temp64, 0xff0000ff);
2398         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2399         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2400     }
2401
2402     /* texture ==> offscreenplain, same size */
2403     if(surf_tex64 && surf_offscreen64) {
2404         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2405         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2406     }
2407
2408     /* texture ==> rendertarget texture, same size */
2409     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         /* We can't lock rendertarget textures, so copy to our temp surface first */
2414         if (hr == D3D_OK) {
2415             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2416             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2417         }
2418
2419         if (hr == D3D_OK) {
2420             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2421             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2422         }
2423     }
2424
2425     /* texture ==> rendertarget surface, same size */
2426     if(surf_tex64 && surf_rt_dest64) {
2427         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2428         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429
2430         if (hr == D3D_OK) {
2431             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2432             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2433         }
2434     }
2435
2436     /* texture ==> texture, same size (should fail) */
2437     if(surf_tex64 && surf_tex_dest64) {
2438         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2439         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2440     }
2441
2442     /* Fill the surface of the smaller regular texture with red */
2443     if (surf_tex32 && surf_temp32) {
2444         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2445         fill_surface(surf_temp32, 0xffff0000);
2446         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2447         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2448     }
2449
2450     /* texture ==> offscreenplain, scaling (should fail) */
2451     if(surf_tex32 && surf_offscreen64) {
2452         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2454     }
2455
2456     /* texture ==> rendertarget texture, scaling */
2457     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2458         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2459         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2460
2461         /* We can't lock rendertarget textures, so copy to our temp surface first */
2462         if (hr == D3D_OK) {
2463             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2464             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2465         }
2466
2467         if (hr == D3D_OK) {
2468             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2469             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2470         }
2471     }
2472
2473     /* texture ==> rendertarget surface, scaling */
2474     if(surf_tex32 && surf_rt_dest64) {
2475         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2476         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2479         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2480     }
2481
2482     /* texture ==> texture, scaling (should fail) */
2483     if(surf_tex32 && surf_tex_dest64) {
2484         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2485         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2486     }
2487
2488     /*****************************************************************
2489      * Tests for when the source parameter is a rendertarget texture *
2490      *****************************************************************/
2491
2492     /* Fill the surface of the rendertarget texture with white */
2493     if (surf_tex_rt64 && surf_temp64) {
2494         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2495         fill_surface(surf_temp64, 0xffffffff);
2496         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2497         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2498     }
2499
2500     /* rendertarget texture ==> offscreenplain, same size */
2501     if(surf_tex_rt64 && surf_offscreen64) {
2502         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2503         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2504     }
2505
2506     /* rendertarget texture ==> rendertarget texture, same size */
2507     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2508         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2509         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2510
2511         /* We can't lock rendertarget textures, so copy to our temp surface first */
2512         if (hr == D3D_OK) {
2513             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2514             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2515         }
2516
2517         if (hr == D3D_OK) {
2518             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2519             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2520         }
2521     }
2522
2523     /* rendertarget texture ==> rendertarget surface, same size */
2524     if(surf_tex_rt64 && surf_rt_dest64) {
2525         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2526         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2527
2528         if (hr == D3D_OK) {
2529             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2530             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2531         }
2532     }
2533
2534     /* rendertarget texture ==> texture, same size (should fail) */
2535     if(surf_tex_rt64 && surf_tex_dest64) {
2536         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2537         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2538     }
2539
2540     /* Fill the surface of the smaller rendertarget texture with red */
2541     if (surf_tex_rt32 && surf_temp32) {
2542         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2543         fill_surface(surf_temp32, 0xffff0000);
2544         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2545         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2546     }
2547
2548     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2549     if(surf_tex_rt32 && surf_offscreen64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2551         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2552     }
2553
2554     /* rendertarget texture ==> rendertarget texture, scaling */
2555     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2556         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2557         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2558
2559         /* We can't lock rendertarget textures, so copy to our temp surface first */
2560         if (hr == D3D_OK) {
2561             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2562             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2563         }
2564
2565         if (hr == D3D_OK) {
2566             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2567             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2568         }
2569     }
2570
2571     /* rendertarget texture ==> rendertarget surface, scaling */
2572     if(surf_tex_rt32 && surf_rt_dest64) {
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2574         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575
2576         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2577         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2578     }
2579
2580     /* rendertarget texture ==> texture, scaling (should fail) */
2581     if(surf_tex_rt32 && surf_tex_dest64) {
2582         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2583         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2584     }
2585
2586     /*****************************************************************
2587      * Tests for when the source parameter is a rendertarget surface *
2588      *****************************************************************/
2589
2590     /* Fill the surface of the rendertarget surface with black */
2591     if (surf_rt64)
2592         fill_surface(surf_rt64, 0xff000000);
2593
2594     /* rendertarget texture ==> offscreenplain, same size */
2595     if(surf_rt64 && surf_offscreen64) {
2596         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2598     }
2599
2600     /* rendertarget surface ==> rendertarget texture, same size */
2601     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2603         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2604
2605         /* We can't lock rendertarget textures, so copy to our temp surface first */
2606         if (hr == D3D_OK) {
2607             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2608             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2609         }
2610
2611         if (hr == D3D_OK) {
2612             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2613             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2614         }
2615     }
2616
2617     /* rendertarget surface ==> rendertarget surface, same size */
2618     if(surf_rt64 && surf_rt_dest64) {
2619         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2620         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2621
2622         if (hr == D3D_OK) {
2623             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2624             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2625         }
2626     }
2627
2628     /* rendertarget surface ==> texture, same size (should fail) */
2629     if(surf_rt64 && surf_tex_dest64) {
2630         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2631         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2632     }
2633
2634     /* Fill the surface of the smaller rendertarget texture with red */
2635     if (surf_rt32)
2636         fill_surface(surf_rt32, 0xffff0000);
2637
2638     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2639     if(surf_rt32 && surf_offscreen64) {
2640         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2641         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2642     }
2643
2644     /* rendertarget surface ==> rendertarget texture, scaling */
2645     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2646         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2647         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2648
2649         /* We can't lock rendertarget textures, so copy to our temp surface first */
2650         if (hr == D3D_OK) {
2651             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2652             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2653         }
2654
2655         if (hr == D3D_OK) {
2656             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2657             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2658         }
2659     }
2660
2661     /* rendertarget surface ==> rendertarget surface, scaling */
2662     if(surf_rt32 && surf_rt_dest64) {
2663         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2664         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2665
2666         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2667         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2668     }
2669
2670     /* rendertarget surface ==> texture, scaling (should fail) */
2671     if(surf_rt32 && surf_tex_dest64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2673         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2674     }
2675
2676     /* TODO: Test when source and destination RECT parameters are given... */
2677     /* TODO: Test format conversions */
2678
2679
2680 out:
2681     /* Clean up */
2682     if (surf_rt32)
2683         IDirect3DSurface9_Release(surf_rt32);
2684     if (surf_rt64)
2685         IDirect3DSurface9_Release(surf_rt64);
2686     if (surf_rt_dest64)
2687         IDirect3DSurface9_Release(surf_rt_dest64);
2688     if (surf_temp32)
2689         IDirect3DSurface9_Release(surf_temp32);
2690     if (surf_temp64)
2691         IDirect3DSurface9_Release(surf_temp64);
2692     if (surf_offscreen32)
2693         IDirect3DSurface9_Release(surf_offscreen32);
2694     if (surf_offscreen64)
2695         IDirect3DSurface9_Release(surf_offscreen64);
2696     if (surf_offscreen_dest64)
2697         IDirect3DSurface9_Release(surf_offscreen_dest64);
2698
2699     if (tex_rt32) {
2700         if (surf_tex_rt32)
2701             IDirect3DSurface9_Release(surf_tex_rt32);
2702         IDirect3DTexture9_Release(tex_rt32);
2703     }
2704     if (tex_rt64) {
2705         if (surf_tex_rt64)
2706             IDirect3DSurface9_Release(surf_tex_rt64);
2707         IDirect3DTexture9_Release(tex_rt64);
2708     }
2709     if (tex_rt_dest64) {
2710         if (surf_tex_rt_dest64)
2711             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2712         IDirect3DTexture9_Release(tex_rt_dest64);
2713     }
2714     if (tex32) {
2715         if (surf_tex32)
2716             IDirect3DSurface9_Release(surf_tex32);
2717         IDirect3DTexture9_Release(tex32);
2718     }
2719     if (tex64) {
2720         if (surf_tex64)
2721             IDirect3DSurface9_Release(surf_tex64);
2722         IDirect3DTexture9_Release(tex64);
2723     }
2724     if (tex_dest64) {
2725         if (surf_tex_dest64)
2726             IDirect3DSurface9_Release(surf_tex_dest64);
2727         IDirect3DTexture9_Release(tex_dest64);
2728     }
2729
2730     if (orig_rt) {
2731         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2732         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2733         IDirect3DSurface9_Release(orig_rt);
2734     }
2735 }
2736
2737 static void maxmip_test(IDirect3DDevice9 *device)
2738 {
2739     IDirect3DTexture9 *texture = NULL;
2740     IDirect3DSurface9 *surface = NULL;
2741     HRESULT hr;
2742     DWORD color;
2743     const float quads[] = {
2744         -1.0,   -1.0,   0.0,    0.0,    0.0,
2745         -1.0,    0.0,   0.0,    0.0,    1.0,
2746          0.0,   -1.0,   0.0,    1.0,    0.0,
2747          0.0,    0.0,   0.0,    1.0,    1.0,
2748
2749          0.0,   -1.0,   0.0,    0.0,    0.0,
2750          0.0,    0.0,   0.0,    0.0,    1.0,
2751          1.0,   -1.0,   0.0,    1.0,    0.0,
2752          1.0,    0.0,   0.0,    1.0,    1.0,
2753
2754          0.0,    0.0,   0.0,    0.0,    0.0,
2755          0.0,    1.0,   0.0,    0.0,    1.0,
2756          1.0,    0.0,   0.0,    1.0,    0.0,
2757          1.0,    1.0,   0.0,    1.0,    1.0,
2758
2759         -1.0,    0.0,   0.0,    0.0,    0.0,
2760         -1.0,    1.0,   0.0,    0.0,    1.0,
2761          0.0,    0.0,   0.0,    1.0,    0.0,
2762          0.0,    1.0,   0.0,    1.0,    1.0,
2763     };
2764
2765     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2766     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2767
2768     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2769                                         &texture, NULL);
2770     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2771     if(!texture)
2772     {
2773         skip("Failed to create test texture\n");
2774         return;
2775     }
2776
2777     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2778     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2779     fill_surface(surface, 0xffff0000);
2780     IDirect3DSurface9_Release(surface);
2781     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2782     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2783     fill_surface(surface, 0xff00ff00);
2784     IDirect3DSurface9_Release(surface);
2785     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2786     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
2787     fill_surface(surface, 0xff0000ff);
2788     IDirect3DSurface9_Release(surface);
2789
2790     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2791     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2792     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2793     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2794
2795     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2796     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2797
2798     hr = IDirect3DDevice9_BeginScene(device);
2799     if(SUCCEEDED(hr))
2800     {
2801         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2802         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2804         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2805
2806         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2807         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2809         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2810
2811         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2812         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2813         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2814         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2815
2816         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2817         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2818         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2819         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2820         hr = IDirect3DDevice9_EndScene(device);
2821         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
2822     }
2823
2824     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2825     color = getPixelColor(device, 160, 360);
2826     ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2827     color = getPixelColor(device, 160, 120);
2828     ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2829     color = getPixelColor(device, 480, 120);
2830     ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2831     color = getPixelColor(device, 480, 360);
2832     ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2833     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2834     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2835
2836     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2837     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2838
2839     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2840     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2841
2842     hr = IDirect3DDevice9_BeginScene(device);
2843     if(SUCCEEDED(hr))
2844     {
2845         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2846         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2847         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2848         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2849
2850         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2851         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2852         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2853         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2854
2855         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2856         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2857         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2858         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2859
2860         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2861         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2862         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2863         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2864         hr = IDirect3DDevice9_EndScene(device);
2865         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
2866     }
2867
2868     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2869      * samples from the highest level in the texture(level 2)
2870      */
2871     color = getPixelColor(device, 160, 360);
2872     ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2873     color = getPixelColor(device, 160, 120);
2874     ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2875     color = getPixelColor(device, 480, 120);
2876     ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2877     color = getPixelColor(device, 480, 360);
2878     ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2879     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2880     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2881
2882     hr = IDirect3DDevice9_BeginScene(device);
2883     if(SUCCEEDED(hr))
2884     {
2885         DWORD ret;
2886
2887         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
2888         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2889         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2890         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2891         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2892         ret = IDirect3DTexture9_SetLOD(texture, 1);
2893         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
2894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2895         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2896
2897         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
2898         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2899         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2900         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2901         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2902         ret = IDirect3DTexture9_SetLOD(texture, 2);
2903         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2904         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2905         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2906
2907         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
2908         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2909         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2910         ret = IDirect3DTexture9_SetLOD(texture, 1);
2911         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
2912         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2913         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2914
2915         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
2916         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2917         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2918         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2919         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2920         ret = IDirect3DTexture9_SetLOD(texture, 1);
2921         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
2922         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2923         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2924         hr = IDirect3DDevice9_EndScene(device);
2925     }
2926
2927     /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2928      * samples from the highest level in the texture(level 2)
2929      */
2930     color = getPixelColor(device, 160, 360);
2931     ok(color == 0x0000FF00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x\n", color);
2932     color = getPixelColor(device, 160, 120);
2933     ok(color == 0x0000FF00, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x\n", color);
2934     color = getPixelColor(device, 480, 120);
2935     ok(color == 0x000000FF, "MapMip 2, LOD 1, point mipfilter has color 0x%08x\n", color);
2936     color = getPixelColor(device, 480, 360);
2937     ok(color == 0x000000FF, "MapMip 2, LOD 1, none mipfilter has color 0x%08x\n", color);
2938     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2939     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2940
2941     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2942     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2943     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2944     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2945     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2946     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2947     IDirect3DTexture9_Release(texture);
2948 }
2949
2950 static void release_buffer_test(IDirect3DDevice9 *device)
2951 {
2952     IDirect3DVertexBuffer9 *vb = NULL;
2953     IDirect3DIndexBuffer9 *ib = NULL;
2954     HRESULT hr;
2955     BYTE *data;
2956     LONG ref;
2957
2958     static const struct vertex quad[] = {
2959         {-1.0,      -1.0,       0.1,        0xffff0000},
2960         {-1.0,       1.0,       0.1,        0xffff0000},
2961         { 1.0,       1.0,       0.1,        0xffff0000},
2962
2963         {-1.0,      -1.0,       0.1,        0xff00ff00},
2964         {-1.0,       1.0,       0.1,        0xff00ff00},
2965         { 1.0,       1.0,       0.1,        0xff00ff00}
2966     };
2967     short indices[] = {3, 4, 5};
2968
2969     /* Index and vertex buffers should always be creatable */
2970     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2971                                               D3DPOOL_MANAGED, &vb, NULL);
2972     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2973     if(!vb) {
2974         skip("Failed to create a vertex buffer\n");
2975         return;
2976     }
2977     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2978     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2979     if(!ib) {
2980         skip("Failed to create an index buffer\n");
2981         return;
2982     }
2983
2984     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2985     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2986     memcpy(data, quad, sizeof(quad));
2987     hr = IDirect3DVertexBuffer9_Unlock(vb);
2988     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2989
2990     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2991     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2992     memcpy(data, indices, sizeof(indices));
2993     hr = IDirect3DIndexBuffer9_Unlock(ib);
2994     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2995
2996     hr = IDirect3DDevice9_SetIndices(device, ib);
2997     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2998     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2999     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3000     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3001     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3002
3003     /* Now destroy the bound index buffer and draw again */
3004     ref = IDirect3DIndexBuffer9_Release(ib);
3005     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3006
3007     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3008     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3009
3010     hr = IDirect3DDevice9_BeginScene(device);
3011     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3012     if(SUCCEEDED(hr))
3013     {
3014         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3015          * making assumptions about the indices or vertices
3016          */
3017         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3018         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3019         hr = IDirect3DDevice9_EndScene(device);
3020         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3021     }
3022
3023     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3024     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3025
3026     hr = IDirect3DDevice9_SetIndices(device, NULL);
3027     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3028     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3029     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3030
3031     /* Index buffer was already destroyed as part of the test */
3032     IDirect3DVertexBuffer9_Release(vb);
3033 }
3034
3035 static void float_texture_test(IDirect3DDevice9 *device)
3036 {
3037     IDirect3D9 *d3d = NULL;
3038     HRESULT hr;
3039     IDirect3DTexture9 *texture = NULL;
3040     D3DLOCKED_RECT lr;
3041     float *data;
3042     DWORD color;
3043     float quad[] = {
3044         -1.0,      -1.0,       0.1,     0.0,    0.0,
3045         -1.0,       1.0,       0.1,     0.0,    1.0,
3046          1.0,      -1.0,       0.1,     1.0,    0.0,
3047          1.0,       1.0,       0.1,     1.0,    1.0,
3048     };
3049
3050     memset(&lr, 0, sizeof(lr));
3051     IDirect3DDevice9_GetDirect3D(device, &d3d);
3052     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3053                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3054         skip("D3DFMT_R32F textures not supported\n");
3055         goto out;
3056     }
3057
3058     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3059                                         D3DPOOL_MANAGED, &texture, NULL);
3060     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3061     if(!texture) {
3062         skip("Failed to create R32F texture\n");
3063         goto out;
3064     }
3065
3066     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3067     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3068     data = lr.pBits;
3069     *data = 0.0;
3070     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3071     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3072
3073     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3074     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3075
3076     hr = IDirect3DDevice9_BeginScene(device);
3077     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3078     if(SUCCEEDED(hr))
3079     {
3080         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3081         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3082
3083         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3084         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3085
3086         hr = IDirect3DDevice9_EndScene(device);
3087         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3088     }
3089     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3090     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3091
3092     color = getPixelColor(device, 240, 320);
3093     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3094
3095     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3096     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3097
3098 out:
3099     if(texture) IDirect3DTexture9_Release(texture);
3100     IDirect3D9_Release(d3d);
3101 }
3102
3103 static void g16r16_texture_test(IDirect3DDevice9 *device)
3104 {
3105     IDirect3D9 *d3d = NULL;
3106     HRESULT hr;
3107     IDirect3DTexture9 *texture = NULL;
3108     D3DLOCKED_RECT lr;
3109     DWORD *data;
3110     DWORD color;
3111     float quad[] = {
3112        -1.0,      -1.0,       0.1,     0.0,    0.0,
3113        -1.0,       1.0,       0.1,     0.0,    1.0,
3114         1.0,      -1.0,       0.1,     1.0,    0.0,
3115         1.0,       1.0,       0.1,     1.0,    1.0,
3116     };
3117
3118     memset(&lr, 0, sizeof(lr));
3119     IDirect3DDevice9_GetDirect3D(device, &d3d);
3120     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3121        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3122            skip("D3DFMT_G16R16 textures not supported\n");
3123            goto out;
3124     }
3125
3126     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3127                                         D3DPOOL_MANAGED, &texture, NULL);
3128     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3129     if(!texture) {
3130         skip("Failed to create D3DFMT_G16R16 texture\n");
3131         goto out;
3132     }
3133
3134     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3135     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3136     data = lr.pBits;
3137     *data = 0x0f00f000;
3138     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3139     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3140
3141     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3142     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3143
3144     hr = IDirect3DDevice9_BeginScene(device);
3145     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3146     if(SUCCEEDED(hr))
3147     {
3148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3150
3151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3152         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3153
3154         hr = IDirect3DDevice9_EndScene(device);
3155         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3156     }
3157     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3158     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3159
3160     color = getPixelColor(device, 240, 320);
3161     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3162        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3163
3164     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3165     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3166
3167 out:
3168     if(texture) IDirect3DTexture9_Release(texture);
3169     IDirect3D9_Release(d3d);
3170 }
3171
3172 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3173 {
3174     HRESULT hr;
3175     IDirect3D9 *d3d;
3176     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3177     D3DCAPS9 caps;
3178     IDirect3DTexture9 *texture = NULL;
3179     IDirect3DVolumeTexture9 *volume = NULL;
3180     unsigned int x, y, z;
3181     D3DLOCKED_RECT lr;
3182     D3DLOCKED_BOX lb;
3183     DWORD color;
3184     UINT w, h;
3185     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3186     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3187                            0.0, 1.0, 0.0, 0.0,
3188                            0.0, 0.0, 1.0, 0.0,
3189                            0.0, 0.0, 0.0, 1.0};
3190     static const D3DVERTEXELEMENT9 decl_elements[] = {
3191         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3192         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3193         D3DDECL_END()
3194     };
3195     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3196         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3197         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3198         D3DDECL_END()
3199     };
3200     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3201         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3202         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3203         D3DDECL_END()
3204     };
3205     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3206                                                  0x00, 0xff, 0x00, 0x00,
3207                                                  0x00, 0x00, 0x00, 0x00,
3208                                                  0x00, 0x00, 0x00, 0x00};
3209
3210     memset(&lr, 0, sizeof(lr));
3211     memset(&lb, 0, sizeof(lb));
3212     IDirect3DDevice9_GetDirect3D(device, &d3d);
3213     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3214                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3215         fmt = D3DFMT_A16B16G16R16;
3216     }
3217     IDirect3D9_Release(d3d);
3218
3219     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3220     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3221     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3222     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3223     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3225     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3226     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3227     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3228     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3229     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3230     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3231     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3232     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3233     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3234     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3235     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3236     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3237     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3238     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3239     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3241     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3242     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3243
3244     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3245     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3246     w = min(1024, caps.MaxTextureWidth);
3247     h = min(1024, caps.MaxTextureHeight);
3248     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3249                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3250     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3251     if(!texture) {
3252         skip("Failed to create the test texture\n");
3253         return;
3254     }
3255
3256     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3257      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3258      * 1.0 in red and green for the x and y coords
3259      */
3260     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3261     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3262     for(y = 0; y < h; y++) {
3263         for(x = 0; x < w; x++) {
3264             double r_f = (double) y / (double) h;
3265             double g_f = (double) x / (double) w;
3266             if(fmt == D3DFMT_A16B16G16R16) {
3267                 unsigned short r, g;
3268                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3269                 r = (unsigned short) (r_f * 65536.0);
3270                 g = (unsigned short) (g_f * 65536.0);
3271                 dst[0] = r;
3272                 dst[1] = g;
3273                 dst[2] = 0;
3274                 dst[3] = 65535;
3275             } else {
3276                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3277                 unsigned char r = (unsigned char) (r_f * 255.0);
3278                 unsigned char g = (unsigned char) (g_f * 255.0);
3279                 dst[0] = 0;
3280                 dst[1] = g;
3281                 dst[2] = r;
3282                 dst[3] = 255;
3283             }
3284         }
3285     }
3286     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3287     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3288     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3289     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3290
3291     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3292     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3293     hr = IDirect3DDevice9_BeginScene(device);
3294     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3295     if(SUCCEEDED(hr))
3296     {
3297         float quad1[] = {
3298             -1.0,      -1.0,       0.1,     1.0,    1.0,
3299             -1.0,       0.0,       0.1,     1.0,    1.0,
3300              0.0,      -1.0,       0.1,     1.0,    1.0,
3301              0.0,       0.0,       0.1,     1.0,    1.0,
3302         };
3303         float quad2[] = {
3304             -1.0,       0.0,       0.1,     1.0,    1.0,
3305             -1.0,       1.0,       0.1,     1.0,    1.0,
3306              0.0,       0.0,       0.1,     1.0,    1.0,
3307              0.0,       1.0,       0.1,     1.0,    1.0,
3308         };
3309         float quad3[] = {
3310              0.0,       0.0,       0.1,     0.5,    0.5,
3311              0.0,       1.0,       0.1,     0.5,    0.5,
3312              1.0,       0.0,       0.1,     0.5,    0.5,
3313              1.0,       1.0,       0.1,     0.5,    0.5,
3314         };
3315         float quad4[] = {
3316              320,       480,       0.1,     1.0,    0.0,    1.0,
3317              320,       240,       0.1,     1.0,    0.0,    1.0,
3318              640,       480,       0.1,     1.0,    0.0,    1.0,
3319              640,       240,       0.1,     1.0,    0.0,    1.0,
3320         };
3321         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3322                           0.0, 0.0, 0.0, 0.0,
3323                           0.0, 0.0, 0.0, 0.0,
3324                           0.0, 0.0, 0.0, 0.0};
3325
3326         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3327         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3328         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3329         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3330         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3331
3332         /* What happens with transforms enabled? */
3333         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3334         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3335         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3336         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3337
3338         /* What happens if 4 coords are used, but only 2 given ?*/
3339         mat[8] = 1.0;
3340         mat[13] = 1.0;
3341         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3342         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3343         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3344         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3346         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3347
3348         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3349          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3350          * due to the coords in the vertices. (turns out red, indeed)
3351          */
3352         memset(mat, 0, sizeof(mat));
3353         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3354         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3355         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3356         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3357         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3358         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3359         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3360         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3361
3362         hr = IDirect3DDevice9_EndScene(device);
3363         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3364     }
3365     color = getPixelColor(device, 160, 360);
3366     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3367     color = getPixelColor(device, 160, 120);
3368     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3369     color = getPixelColor(device, 480, 120);
3370     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3371     color = getPixelColor(device, 480, 360);
3372     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3373     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3374     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3375
3376     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3377     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3378
3379     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3380     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3381     hr = IDirect3DDevice9_BeginScene(device);
3382     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3383     if(SUCCEEDED(hr))
3384     {
3385         float quad1[] = {
3386             -1.0,      -1.0,       0.1,     0.8,    0.2,
3387             -1.0,       0.0,       0.1,     0.8,    0.2,
3388              0.0,      -1.0,       0.1,     0.8,    0.2,
3389              0.0,       0.0,       0.1,     0.8,    0.2,
3390         };
3391         float quad2[] = {
3392             -1.0,       0.0,       0.1,     0.5,    1.0,
3393             -1.0,       1.0,       0.1,     0.5,    1.0,
3394              0.0,       0.0,       0.1,     0.5,    1.0,
3395              0.0,       1.0,       0.1,     0.5,    1.0,
3396         };
3397         float quad3[] = {
3398              0.0,       0.0,       0.1,     0.5,    1.0,
3399              0.0,       1.0,       0.1,     0.5,    1.0,
3400              1.0,       0.0,       0.1,     0.5,    1.0,
3401              1.0,       1.0,       0.1,     0.5,    1.0,
3402         };
3403         float quad4[] = {
3404              0.0,      -1.0,       0.1,     0.8,    0.2,
3405              0.0,       0.0,       0.1,     0.8,    0.2,
3406              1.0,      -1.0,       0.1,     0.8,    0.2,
3407              1.0,       0.0,       0.1,     0.8,    0.2,
3408         };
3409         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3410                           0.0, 0.0, 0.0, 0.0,
3411                           0.0, 1.0, 0.0, 0.0,
3412                           0.0, 0.0, 0.0, 0.0};
3413
3414         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3415          */
3416         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3417         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3418         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3419         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3420
3421         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3422         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3423
3424         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3425          * it behaves like COUNT2 because normal textures require 2 coords
3426          */
3427         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3428         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3429         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3430         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3431
3432         /* Just to be sure, the same as quad2 above */
3433         memset(mat, 0, sizeof(mat));
3434         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3435         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3436         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3437         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3438         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3439         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3440
3441         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3442          * used? And what happens to the first?
3443          */
3444         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3445         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3447         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3448
3449         hr = IDirect3DDevice9_EndScene(device);
3450         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3451     }
3452     color = getPixelColor(device, 160, 360);
3453     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3454     color = getPixelColor(device, 160, 120);
3455     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3456     color = getPixelColor(device, 480, 120);
3457     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3458        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3459     color = getPixelColor(device, 480, 360);
3460     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3461        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3462     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3463     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3464
3465     IDirect3DTexture9_Release(texture);
3466
3467     /* Test projected textures, without any fancy matrices */
3468     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3469     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3470     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3471     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3472     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3473     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3474     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3475     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3476
3477     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3478     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3479     for(x = 0; x < 4; x++) {
3480         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3481     }
3482     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3483     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3484     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3485     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3486
3487     hr = IDirect3DDevice9_BeginScene(device);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3489     if(SUCCEEDED(hr))
3490     {
3491         const float proj_quads[] = {
3492            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3493             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3494            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3495             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3496            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3497             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3498            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3499             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3500         };
3501
3502         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3503         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3504         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3505         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3506
3507         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3508         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3509         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3510         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3511
3512         hr = IDirect3DDevice9_EndScene(device);
3513         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3514     }
3515
3516     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3517     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3518     IDirect3DTexture9_Release(texture);
3519
3520     color = getPixelColor(device, 158, 118);
3521     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3522     color = getPixelColor(device, 162, 118);
3523     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3524     color = getPixelColor(device, 158, 122);
3525     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3526     color = getPixelColor(device, 162, 122);
3527     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3528
3529     color = getPixelColor(device, 158, 178);
3530     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3531     color = getPixelColor(device, 162, 178);
3532     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3533     color = getPixelColor(device, 158, 182);
3534     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3535     color = getPixelColor(device, 162, 182);
3536     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3537
3538     color = getPixelColor(device, 318, 118);
3539     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3540     color = getPixelColor(device, 322, 118);
3541     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3542     color = getPixelColor(device, 318, 122);
3543     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3544     color = getPixelColor(device, 322, 122);
3545     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3546
3547     color = getPixelColor(device, 318, 178);
3548     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3549     color = getPixelColor(device, 322, 178);
3550     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3551     color = getPixelColor(device, 318, 182);
3552     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3553     color = getPixelColor(device, 322, 182);
3554     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3555
3556     color = getPixelColor(device, 238, 298);
3557     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3558     color = getPixelColor(device, 242, 298);
3559     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3560     color = getPixelColor(device, 238, 302);
3561     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3562     color = getPixelColor(device, 242, 302);
3563     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3564
3565     color = getPixelColor(device, 238, 388);
3566     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3567     color = getPixelColor(device, 242, 388);
3568     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3569     color = getPixelColor(device, 238, 392);
3570     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3571     color = getPixelColor(device, 242, 392);
3572     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3573
3574     color = getPixelColor(device, 478, 298);
3575     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3576     color = getPixelColor(device, 482, 298);
3577     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3578     color = getPixelColor(device, 478, 302);
3579     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3580     color = getPixelColor(device, 482, 302);
3581     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3582
3583     color = getPixelColor(device, 478, 388);
3584     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3585     color = getPixelColor(device, 482, 388);
3586     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3587     color = getPixelColor(device, 478, 392);
3588     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3589     color = getPixelColor(device, 482, 392);
3590     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3591
3592     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3593     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3594
3595     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3596     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3597     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3598      * Thus watch out if sampling from texels between 0 and 1.
3599      */
3600     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3601     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3602        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3603     if(!volume) {
3604         skip("Failed to create a volume texture\n");
3605         goto out;
3606     }
3607
3608     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3609     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3610     for(z = 0; z < 32; z++) {
3611         for(y = 0; y < 32; y++) {
3612             for(x = 0; x < 32; x++) {
3613                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3614                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3615                 float r_f = (float) x / 31.0;
3616                 float g_f = (float) y / 31.0;
3617                 float b_f = (float) z / 31.0;
3618
3619                 if(fmt == D3DFMT_A16B16G16R16) {
3620                     unsigned short *mem_s = mem;
3621                     mem_s[0]  = r_f * 65535.0;
3622                     mem_s[1]  = g_f * 65535.0;
3623                     mem_s[2]  = b_f * 65535.0;
3624                     mem_s[3]  = 65535;
3625                 } else {
3626                     unsigned char *mem_c = mem;
3627                     mem_c[0]  = b_f * 255.0;
3628                     mem_c[1]  = g_f * 255.0;
3629                     mem_c[2]  = r_f * 255.0;
3630                     mem_c[3]  = 255;
3631                 }
3632             }
3633         }
3634     }
3635     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3636     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3639     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3640
3641     hr = IDirect3DDevice9_BeginScene(device);
3642     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3643     if(SUCCEEDED(hr))
3644     {
3645         float quad1[] = {
3646             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3647             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3648              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3649              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3650         };
3651         float quad2[] = {
3652             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3653             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3654              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3655              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3656         };
3657         float quad3[] = {
3658              0.0,       0.0,       0.1,     0.0,    0.0,
3659              0.0,       1.0,       0.1,     0.0,    0.0,
3660              1.0,       0.0,       0.1,     0.0,    0.0,
3661              1.0,       1.0,       0.1,     0.0,    0.0
3662         };
3663         float quad4[] = {
3664              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3665              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3666              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3667              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3668         };
3669         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3670                          0.0, 0.0, 1.0, 0.0,
3671                          0.0, 1.0, 0.0, 0.0,
3672                          0.0, 0.0, 0.0, 1.0};
3673         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3674         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3675
3676         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3677          * values
3678          */
3679         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3680         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3682         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3683         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3684         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3685
3686         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3687          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3688          * otherwise the w will be missing(blue).
3689          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3690          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3691          */
3692         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3693         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3694         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3695         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3696
3697         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3698         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3699         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3700         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3701         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3702         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3703         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3704         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3705         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3706
3707         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3708          * disable. ATI extends it up to the amount of values needed for the volume texture
3709          */
3710         memset(mat, 0, sizeof(mat));
3711         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3712         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3713         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3714         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3715         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3716         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3717         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3718         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3719
3720         hr = IDirect3DDevice9_EndScene(device);
3721         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3722     }
3723
3724     color = getPixelColor(device, 160, 360);
3725     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3726     color = getPixelColor(device, 160, 120);
3727     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3728        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3729     color = getPixelColor(device, 480, 120);
3730     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3731     color = getPixelColor(device, 480, 360);
3732     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3733
3734     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3735     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3736
3737     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3738     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3739     hr = IDirect3DDevice9_BeginScene(device);
3740     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3741     if(SUCCEEDED(hr))
3742     {
3743         float quad1[] = {
3744             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3745             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3746              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3747              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3748         };
3749         float quad2[] = {
3750             -1.0,       0.0,       0.1,
3751             -1.0,       1.0,       0.1,
3752              0.0,       0.0,       0.1,
3753              0.0,       1.0,       0.1,
3754         };
3755         float quad3[] = {
3756              0.0,       0.0,       0.1,     1.0,
3757              0.0,       1.0,       0.1,     1.0,
3758              1.0,       0.0,       0.1,     1.0,
3759              1.0,       1.0,       0.1,     1.0
3760         };
3761         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
3762                            0.0, 0.0, 0.0, 0.0,
3763                            0.0, 0.0, 0.0, 0.0,
3764                            0.0, 1.0, 0.0, 0.0};
3765         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3766                            1.0, 0.0, 0.0, 0.0,
3767                            0.0, 1.0, 0.0, 0.0,
3768                            0.0, 0.0, 1.0, 0.0};
3769         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3770         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3771
3772         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3773          */
3774         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3775         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3776         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3777         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3778         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3779         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3780
3781         /* None passed */
3782         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3783         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3784         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3785         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3786         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3787         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3788
3789         /* 4 used, 1 passed */
3790         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3791         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3792         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3793         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3794         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3795         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3796
3797         hr = IDirect3DDevice9_EndScene(device);
3798         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3799     }
3800     color = getPixelColor(device, 160, 360);
3801     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3802     color = getPixelColor(device, 160, 120);
3803     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3804     color = getPixelColor(device, 480, 120);
3805     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3806     /* Quad4: unused */
3807
3808     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3809     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3810
3811     IDirect3DVolumeTexture9_Release(volume);
3812
3813     out:
3814     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3815     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3816     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3817     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3818     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3819     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3820     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3821     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3822     IDirect3DVertexDeclaration9_Release(decl);
3823     IDirect3DVertexDeclaration9_Release(decl2);
3824     IDirect3DVertexDeclaration9_Release(decl3);
3825 }
3826
3827 static void texdepth_test(IDirect3DDevice9 *device)
3828 {
3829     IDirect3DPixelShader9 *shader;
3830     HRESULT hr;
3831     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
3832     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
3833     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
3834     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3835     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3836     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
3837     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
3838     DWORD shader_code[] = {
3839         0xffff0104,                                                                 /* ps_1_4               */
3840         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
3841         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
3842         0x0000fffd,                                                                 /* phase                */
3843         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
3844         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
3845         0x0000ffff                                                                  /* end                  */
3846     };
3847     DWORD color;
3848     float vertex[] = {
3849        -1.0,   -1.0,    0.0,
3850         1.0,   -1.0,    1.0,
3851        -1.0,    1.0,    0.0,
3852         1.0,    1.0,    1.0
3853     };
3854
3855     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3856     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3857
3858     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3859     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3860     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3861     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3862     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3863     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3864     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3865     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3866     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3867     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
3868
3869     /* Fill the depth buffer with a gradient */
3870     hr = IDirect3DDevice9_BeginScene(device);
3871     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3872     if(SUCCEEDED(hr))
3873     {
3874         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3875         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3876         hr = IDirect3DDevice9_EndScene(device);
3877         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3878     }
3879
3880     /* Now perform the actual tests. Same geometry, but with the shader */
3881     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3882     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3883     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3884     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3885     hr = IDirect3DDevice9_SetPixelShader(device, shader);
3886     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3887
3888     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3889     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3890     hr = IDirect3DDevice9_BeginScene(device);
3891     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3892     if(SUCCEEDED(hr))
3893     {
3894         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3895         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3896
3897         hr = IDirect3DDevice9_EndScene(device);
3898         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3899     }
3900
3901     color = getPixelColor(device, 158, 240);
3902     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3903     color = getPixelColor(device, 162, 240);
3904     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3905
3906     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3907     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3908
3909     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3910     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3911
3912     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3913     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3914     hr = IDirect3DDevice9_BeginScene(device);
3915     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3916     if(SUCCEEDED(hr))
3917     {
3918         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3919         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3920
3921         hr = IDirect3DDevice9_EndScene(device);
3922         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3923     }
3924
3925     color = getPixelColor(device, 318, 240);
3926     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3927     color = getPixelColor(device, 322, 240);
3928     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3929
3930     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3931     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3932
3933     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3934     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3935
3936     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3937     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3938     hr = IDirect3DDevice9_BeginScene(device);
3939     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3940     if(SUCCEEDED(hr))
3941     {
3942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3943         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3944
3945         hr = IDirect3DDevice9_EndScene(device);
3946         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3947     }
3948
3949     color = getPixelColor(device, 1, 240);
3950     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3951
3952     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3953     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3954
3955     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3956     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3957
3958     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3959     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3960     hr = IDirect3DDevice9_BeginScene(device);
3961     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3962     if(SUCCEEDED(hr))
3963     {
3964         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3965         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3966
3967         hr = IDirect3DDevice9_EndScene(device);
3968         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3969     }
3970     color = getPixelColor(device, 318, 240);
3971     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3972     color = getPixelColor(device, 322, 240);
3973     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3974
3975     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3976     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3977
3978     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3979     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
3980
3981     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3982     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3983     hr = IDirect3DDevice9_BeginScene(device);
3984     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3985     if(SUCCEEDED(hr))
3986     {
3987         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3988         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3989
3990         hr = IDirect3DDevice9_EndScene(device);
3991         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3992     }
3993
3994     color = getPixelColor(device, 1, 240);
3995     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3996
3997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3998     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3999
4000     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4001     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4002
4003     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4004     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4005     hr = IDirect3DDevice9_BeginScene(device);
4006     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4007     if(SUCCEEDED(hr))
4008     {
4009         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4010         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4011
4012         hr = IDirect3DDevice9_EndScene(device);
4013         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4014     }
4015
4016     color = getPixelColor(device, 638, 240);
4017     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4018
4019     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4020     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4021
4022     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4023     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4024
4025     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4026     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4027     hr = IDirect3DDevice9_BeginScene(device);
4028     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4029     if(SUCCEEDED(hr))
4030     {
4031         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4032         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4033
4034         hr = IDirect3DDevice9_EndScene(device);
4035         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4036     }
4037
4038     color = getPixelColor(device, 638, 240);
4039     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4040
4041     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4043
4044     /* Cleanup */
4045     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4046     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4047     IDirect3DPixelShader9_Release(shader);
4048
4049     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4050     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4051     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4052     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4053 }
4054
4055 static void texkill_test(IDirect3DDevice9 *device)
4056 {
4057     IDirect3DPixelShader9 *shader;
4058     HRESULT hr;
4059     DWORD color;
4060
4061     const float vertex[] = {
4062     /*                          bottom  top    right    left */
4063         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4064          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4065         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4066          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4067     };
4068
4069     DWORD shader_code_11[] = {
4070     0xffff0101,                                                             /* ps_1_1                     */
4071     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4072     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4073     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4074     0x0000ffff                                                              /* end                        */
4075     };
4076     DWORD shader_code_20[] = {
4077     0xffff0200,                                                             /* ps_2_0                     */
4078     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4079     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4080     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4081     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4082     0x0000ffff                                                              /* end                        */
4083     };
4084
4085     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4086     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4087     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4088     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4089
4090     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4091     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4092     hr = IDirect3DDevice9_BeginScene(device);
4093     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4094     if(SUCCEEDED(hr))
4095     {
4096         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4097         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4098         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4099         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4100         hr = IDirect3DDevice9_EndScene(device);
4101         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4102     }
4103     color = getPixelColor(device, 63, 46);
4104     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4105     color = getPixelColor(device, 66, 46);
4106     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4107     color = getPixelColor(device, 63, 49);
4108     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4109     color = getPixelColor(device, 66, 49);
4110     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4111
4112     color = getPixelColor(device, 578, 46);
4113     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4114     color = getPixelColor(device, 575, 46);
4115     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4116     color = getPixelColor(device, 578, 49);
4117     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4118     color = getPixelColor(device, 575, 49);
4119     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4120
4121     color = getPixelColor(device, 63, 430);
4122     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4123     color = getPixelColor(device, 63, 433);
4124     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4125     color = getPixelColor(device, 66, 433);
4126     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4127     color = getPixelColor(device, 66, 430);
4128     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4129
4130     color = getPixelColor(device, 578, 430);
4131     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4132     color = getPixelColor(device, 578, 433);
4133     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4134     color = getPixelColor(device, 575, 433);
4135     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4136     color = getPixelColor(device, 575, 430);
4137     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4138
4139     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4140     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4141
4142     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4143     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4144     IDirect3DPixelShader9_Release(shader);
4145
4146     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4147     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4148     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4149     if(FAILED(hr)) {
4150         skip("Failed to create 2.0 test shader, most likely not supported\n");
4151         return;
4152     }
4153
4154     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4155     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4156     hr = IDirect3DDevice9_BeginScene(device);
4157     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4158     if(SUCCEEDED(hr))
4159     {
4160         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4161         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4162         hr = IDirect3DDevice9_EndScene(device);
4163         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4164     }
4165
4166     color = getPixelColor(device, 63, 46);
4167     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4168     color = getPixelColor(device, 66, 46);
4169     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4170     color = getPixelColor(device, 63, 49);
4171     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4172     color = getPixelColor(device, 66, 49);
4173     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4174
4175     color = getPixelColor(device, 578, 46);
4176     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4177     color = getPixelColor(device, 575, 46);
4178     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4179     color = getPixelColor(device, 578, 49);
4180     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4181     color = getPixelColor(device, 575, 49);
4182     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4183
4184     color = getPixelColor(device, 63, 430);
4185     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4186     color = getPixelColor(device, 63, 433);
4187     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4188     color = getPixelColor(device, 66, 433);
4189     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4190     color = getPixelColor(device, 66, 430);
4191     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4192
4193     color = getPixelColor(device, 578, 430);
4194     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4195     color = getPixelColor(device, 578, 433);
4196     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4197     color = getPixelColor(device, 575, 433);
4198     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4199     color = getPixelColor(device, 575, 430);
4200     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4201
4202     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4203     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4204
4205     /* Cleanup */
4206     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4207     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4208     IDirect3DPixelShader9_Release(shader);
4209 }
4210
4211 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4212 {
4213     IDirect3D9 *d3d9;
4214     HRESULT hr;
4215     IDirect3DTexture9 *texture;
4216     IDirect3DPixelShader9 *shader;
4217     IDirect3DPixelShader9 *shader2;
4218     D3DLOCKED_RECT lr;
4219     DWORD color;
4220     DWORD shader_code[] = {
4221         0xffff0101,                             /* ps_1_1       */
4222         0x00000042, 0xb00f0000,                 /* tex t0       */
4223         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4224         0x0000ffff                              /* end          */
4225     };
4226     DWORD shader_code2[] = {
4227         0xffff0101,                             /* ps_1_1       */
4228         0x00000042, 0xb00f0000,                 /* tex t0       */
4229         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4230         0x0000ffff                              /* end          */
4231     };
4232
4233     float quad[] = {
4234        -1.0,   -1.0,   0.1,     0.5,    0.5,
4235         1.0,   -1.0,   0.1,     0.5,    0.5,
4236        -1.0,    1.0,   0.1,     0.5,    0.5,
4237         1.0,    1.0,   0.1,     0.5,    0.5,
4238     };
4239
4240     memset(&lr, 0, sizeof(lr));
4241     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4242     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4243                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4244     IDirect3D9_Release(d3d9);
4245     if(FAILED(hr)) {
4246         skip("No D3DFMT_X8L8V8U8 support\n");
4247         return;
4248     };
4249
4250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4252
4253     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4254     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4255     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4256     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4257     *((DWORD *) lr.pBits) = 0x11ca3141;
4258     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4259     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4260
4261     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4262     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4263     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4264     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4265
4266     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4268     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4269     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4270     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4271     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4272
4273     hr = IDirect3DDevice9_BeginScene(device);
4274     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4275     if(SUCCEEDED(hr))
4276     {
4277         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4278         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4279
4280         hr = IDirect3DDevice9_EndScene(device);
4281         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4282     }
4283     color = getPixelColor(device, 578, 430);
4284     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4285        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4286     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4287     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4288
4289     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4290     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4291     hr = IDirect3DDevice9_BeginScene(device);
4292     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4293     if(SUCCEEDED(hr))
4294     {
4295         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4296         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4297
4298         hr = IDirect3DDevice9_EndScene(device);
4299         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4300     }
4301     color = getPixelColor(device, 578, 430);
4302     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4303     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4304     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4305
4306     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4307     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4308     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4309     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4310     IDirect3DPixelShader9_Release(shader);
4311     IDirect3DPixelShader9_Release(shader2);
4312     IDirect3DTexture9_Release(texture);
4313 }
4314
4315 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4316 {
4317     HRESULT hr;
4318     IDirect3D9 *d3d;
4319     IDirect3DTexture9 *texture = NULL;
4320     IDirect3DSurface9 *surface;
4321     DWORD color;
4322     const RECT r1 = {256, 256, 512, 512};
4323     const RECT r2 = {512, 256, 768, 512};
4324     const RECT r3 = {256, 512, 512, 768};
4325     const RECT r4 = {512, 512, 768, 768};
4326     unsigned int x, y;
4327     D3DLOCKED_RECT lr;
4328     memset(&lr, 0, sizeof(lr));
4329
4330     IDirect3DDevice9_GetDirect3D(device, &d3d);
4331     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4332        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4333         skip("No autogenmipmap support\n");
4334         IDirect3D9_Release(d3d);
4335         return;
4336     }
4337     IDirect3D9_Release(d3d);
4338
4339     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4340     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4341
4342     /* Make the mipmap big, so that a smaller mipmap is used
4343      */
4344     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4345                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4346     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4347
4348     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4349     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4350     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4351     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4352     for(y = 0; y < 1024; y++) {
4353         for(x = 0; x < 1024; x++) {
4354             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4355             POINT pt;
4356
4357             pt.x = x;
4358             pt.y = y;
4359             if(PtInRect(&r1, pt)) {
4360                 *dst = 0xffff0000;
4361             } else if(PtInRect(&r2, pt)) {
4362                 *dst = 0xff00ff00;
4363             } else if(PtInRect(&r3, pt)) {
4364                 *dst = 0xff0000ff;
4365             } else if(PtInRect(&r4, pt)) {
4366                 *dst = 0xff000000;
4367             } else {
4368                 *dst = 0xffffffff;
4369             }
4370         }
4371     }
4372     hr = IDirect3DSurface9_UnlockRect(surface);
4373     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4374     IDirect3DSurface9_Release(surface);
4375
4376     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4377     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4378     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4379     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4380
4381     hr = IDirect3DDevice9_BeginScene(device);
4382     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4383     if(SUCCEEDED(hr)) {
4384         const float quad[] =  {
4385            -0.5,   -0.5,    0.1,    0.0,    0.0,
4386            -0.5,    0.5,    0.1,    0.0,    1.0,
4387             0.5,   -0.5,    0.1,    1.0,    0.0,
4388             0.5,    0.5,    0.1,    1.0,    1.0
4389         };
4390
4391         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4392         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4394         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4395         hr = IDirect3DDevice9_EndScene(device);
4396         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4397     }
4398     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4399     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4400     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4401     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4402     IDirect3DTexture9_Release(texture);
4403
4404     color = getPixelColor(device, 200, 200);
4405     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4406     color = getPixelColor(device, 280, 200);
4407     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4408     color = getPixelColor(device, 360, 200);
4409     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4410     color = getPixelColor(device, 440, 200);
4411     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4412     color = getPixelColor(device, 200, 270);
4413     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4414     color = getPixelColor(device, 280, 270);
4415     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4416     color = getPixelColor(device, 360, 270);
4417     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4418     color = getPixelColor(device, 440, 270);
4419     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4420     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4421     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4422 }
4423
4424 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4425 {
4426     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4427     IDirect3DVertexDeclaration9 *decl;
4428     HRESULT hr;
4429     DWORD color;
4430     DWORD shader_code_11[] =  {
4431         0xfffe0101,                                         /* vs_1_1           */
4432         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4433         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4434         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4435         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4436         0x0000ffff                                          /* end              */
4437     };
4438     DWORD shader_code_11_2[] =  {
4439         0xfffe0101,                                         /* vs_1_1           */
4440         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4441         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4442         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4443         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4444         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4445         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4446         0x0000ffff                                          /* end              */
4447     };
4448     DWORD shader_code_20[] =  {
4449         0xfffe0200,                                         /* vs_2_0           */
4450         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4451         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4452         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4453         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4454         0x0000ffff                                          /* end              */
4455     };
4456     DWORD shader_code_20_2[] =  {
4457         0xfffe0200,                                         /* vs_2_0           */
4458         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4459         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4460         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4461         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4462         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4463         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4464         0x0000ffff                                          /* end              */
4465     };
4466     static const D3DVERTEXELEMENT9 decl_elements[] = {
4467         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4468         D3DDECL_END()
4469     };
4470     float quad1[] = {
4471         -1.0,   -1.0,   0.1,
4472          0.0,   -1.0,   0.1,
4473         -1.0,    0.0,   0.1,
4474          0.0,    0.0,   0.1
4475     };
4476     float quad2[] = {
4477          0.0,   -1.0,   0.1,
4478          1.0,   -1.0,   0.1,
4479          0.0,    0.0,   0.1,
4480          1.0,    0.0,   0.1
4481     };
4482     float quad3[] = {
4483          0.0,    0.0,   0.1,
4484          1.0,    0.0,   0.1,
4485          0.0,    1.0,   0.1,
4486          1.0,    1.0,   0.1
4487     };
4488     float quad4[] = {
4489         -1.0,    0.0,   0.1,
4490          0.0,    0.0,   0.1,
4491         -1.0,    1.0,   0.1,
4492          0.0,    1.0,   0.1
4493     };
4494     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4495     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4496
4497     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4498     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4499
4500     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4501     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4502     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4503     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4504     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4505     if(FAILED(hr)) shader_20 = NULL;
4506     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4507     if(FAILED(hr)) shader_20_2 = NULL;
4508     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4509     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4510
4511     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4512     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4513     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4514     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4515     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4516     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4517
4518     hr = IDirect3DDevice9_BeginScene(device);
4519     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4520     if(SUCCEEDED(hr))
4521     {
4522         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4523         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4524         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4525         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4526
4527         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4528         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4529         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4530         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4531
4532         if(shader_20) {
4533             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4534             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4535             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4536             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4537         }
4538
4539         if(shader_20_2) {
4540             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4541             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4542             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4543             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4544         }
4545
4546         hr = IDirect3DDevice9_EndScene(device);
4547         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4548     }
4549
4550     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4551     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4552     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4553     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4554
4555     color = getPixelColor(device, 160, 360);
4556     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4557        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4558     color = getPixelColor(device, 480, 360);
4559     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4560        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4561     if(shader_20) {
4562         color = getPixelColor(device, 160, 120);
4563         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4564            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4565     }
4566     if(shader_20_2) {
4567         color = getPixelColor(device, 480, 120);
4568         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4569            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4570     }
4571     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4573
4574     IDirect3DVertexDeclaration9_Release(decl);
4575     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4576     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4577     IDirect3DVertexShader9_Release(shader_11_2);
4578     IDirect3DVertexShader9_Release(shader_11);
4579 }
4580
4581 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4582 {
4583     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4584     HRESULT hr;
4585     DWORD color;
4586     DWORD shader_code_11[] =  {
4587         0xffff0101,                                         /* ps_1_1           */
4588         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4589         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4590         0x0000ffff                                          /* end              */
4591     };
4592     DWORD shader_code_12[] =  {
4593         0xffff0102,                                         /* ps_1_2           */
4594         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4595         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4596         0x0000ffff                                          /* end              */
4597     };
4598     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4599      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4600      * During development of this test, 1.3 shaders were verified too
4601      */
4602     DWORD shader_code_14[] =  {
4603         0xffff0104,                                         /* ps_1_4           */
4604         /* Try to make one constant local. It gets clamped too, although the binary contains
4605          * the bigger numbers
4606          */
4607         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4608         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4609         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4610         0x0000ffff                                          /* end              */
4611     };
4612     DWORD shader_code_20[] =  {
4613         0xffff0200,                                         /* ps_2_0           */
4614         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4615         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4616         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4617         0x0000ffff                                          /* end              */
4618     };
4619     float quad1[] = {
4620         -1.0,   -1.0,   0.1,
4621          0.0,   -1.0,   0.1,
4622         -1.0,    0.0,   0.1,
4623          0.0,    0.0,   0.1
4624     };
4625     float quad2[] = {
4626          0.0,   -1.0,   0.1,
4627          1.0,   -1.0,   0.1,
4628          0.0,    0.0,   0.1,
4629          1.0,    0.0,   0.1
4630     };
4631     float quad3[] = {
4632          0.0,    0.0,   0.1,
4633          1.0,    0.0,   0.1,
4634          0.0,    1.0,   0.1,
4635          1.0,    1.0,   0.1
4636     };
4637     float quad4[] = {
4638         -1.0,    0.0,   0.1,
4639          0.0,    0.0,   0.1,
4640         -1.0,    1.0,   0.1,
4641          0.0,    1.0,   0.1
4642     };
4643     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4644     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4645
4646     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4647     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4648
4649     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4650     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4651     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4652     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4653     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4654     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4655     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4656     if(FAILED(hr)) shader_20 = NULL;
4657
4658     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4659     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4660     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4661     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4662     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4663     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4664
4665     hr = IDirect3DDevice9_BeginScene(device);
4666     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4667     if(SUCCEEDED(hr))
4668     {
4669         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4670         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4671         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4672         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4673
4674         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4675         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4676         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4677         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4678
4679         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4680         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4681         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4682         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4683
4684         if(shader_20) {
4685             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4686             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4687             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4688             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4689         }
4690
4691         hr = IDirect3DDevice9_EndScene(device);
4692         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4693     }
4694     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4695     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4696
4697     color = getPixelColor(device, 160, 360);
4698     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4699        "quad 1 has color %08x, expected 0x00808000\n", color);
4700     color = getPixelColor(device, 480, 360);
4701     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4702        "quad 2 has color %08x, expected 0x00808000\n", color);
4703     color = getPixelColor(device, 480, 120);
4704     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4705        "quad 3 has color %08x, expected 0x00808000\n", color);
4706     if(shader_20) {
4707         color = getPixelColor(device, 160, 120);
4708         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4709            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4710     }
4711     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4712     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4713
4714     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4715     IDirect3DPixelShader9_Release(shader_14);
4716     IDirect3DPixelShader9_Release(shader_12);
4717     IDirect3DPixelShader9_Release(shader_11);
4718 }
4719
4720 static void dp2add_ps_test(IDirect3DDevice9 *device)
4721 {
4722     IDirect3DPixelShader9 *shader_dp2add = NULL;
4723     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4724     HRESULT hr;
4725     DWORD color;
4726
4727     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4728      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4729      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4730      * r0 first.
4731      * The result here for the r,g,b components should be roughly 0.5:
4732      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4733     static const DWORD shader_code_dp2add[] =  {
4734         0xffff0200,                                                             /* ps_2_0                       */
4735         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
4736
4737         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
4738         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
4739
4740         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
4741         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
4742         0x0000ffff                                                              /* end                          */
4743     };
4744
4745     /* Test the _sat modifier, too.  Result here should be:
4746      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4747      *      _SAT: ==> 1.0
4748      *   ADD: (1.0 + -0.5) = 0.5
4749      */
4750     static const DWORD shader_code_dp2add_sat[] =  {
4751         0xffff0200,                                                             /* ps_2_0                           */
4752         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
4753
4754         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
4755         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
4756         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
4757
4758         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
4759         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
4760         0x0000ffff                                                              /* end                              */
4761     };
4762
4763     const float quad[] = {
4764         -1.0,   -1.0,   0.1,
4765          1.0,   -1.0,   0.1,
4766         -1.0,    1.0,   0.1,
4767          1.0,    1.0,   0.1
4768     };
4769
4770
4771     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4772     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4773
4774     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4775     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4776
4777     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4778     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4779
4780     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4781     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4782
4783     if (shader_dp2add) {
4784
4785         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4786         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4787
4788         hr = IDirect3DDevice9_BeginScene(device);
4789         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4790         if(SUCCEEDED(hr))
4791         {
4792             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4793             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4794
4795             hr = IDirect3DDevice9_EndScene(device);
4796             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4797         }
4798
4799         color = getPixelColor(device, 360, 240);
4800         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4801                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4802
4803         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4804         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4805
4806         IDirect3DPixelShader9_Release(shader_dp2add);
4807     } else {
4808         skip("dp2add shader creation failed\n");
4809     }
4810
4811     if (shader_dp2add_sat) {
4812
4813         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4814         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4815
4816         hr = IDirect3DDevice9_BeginScene(device);
4817         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4818         if(SUCCEEDED(hr))
4819         {
4820             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4821             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4822
4823             hr = IDirect3DDevice9_EndScene(device);
4824             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4825         }
4826
4827         color = getPixelColor(device, 360, 240);
4828         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
4829                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4830
4831         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4832         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4833
4834         IDirect3DPixelShader9_Release(shader_dp2add_sat);
4835     } else {
4836         skip("dp2add shader creation failed\n");
4837     }
4838
4839     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4840     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4841 }
4842
4843 static void cnd_test(IDirect3DDevice9 *device)
4844 {
4845     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4846     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4847     HRESULT hr;
4848     DWORD color;
4849     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4850      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4851      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4852      */
4853     DWORD shader_code_11[] =  {
4854         0xffff0101,                                                                 /* ps_1_1               */
4855         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4856         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4857         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
4858         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4859         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4860         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4861         0x0000ffff                                                                  /* end                  */
4862     };
4863     DWORD shader_code_12[] =  {
4864         0xffff0102,                                                                 /* ps_1_2               */
4865         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4866         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4867         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4868         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
4869         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4870         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4871         0x0000ffff                                                                  /* end                  */
4872     };
4873     DWORD shader_code_13[] =  {
4874         0xffff0103,                                                                 /* ps_1_3               */
4875         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
4876         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
4877         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
4878         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
4879         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
4880         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
4881         0x0000ffff                                                                  /* end                  */
4882     };
4883     DWORD shader_code_14[] =  {
4884         0xffff0104,                                                                 /* ps_1_3               */
4885         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
4886         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
4887         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
4888         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
4889         0x0000ffff                                                                  /* end                  */
4890     };
4891
4892     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4893      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4894      * set by the compiler, it was added manually after compilation. It isn't always allowed,
4895      * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4896      * native CreatePixelShader returns an error.
4897      *
4898      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4899      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4900      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4901      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4902      */
4903     DWORD shader_code_11_coissue[] =  {
4904         0xffff0101,                                                             /* ps_1_1                   */
4905         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4906         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4907         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4908         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4909         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4910         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4911         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4912         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4913         /* 0x40000000 = D3DSI_COISSUE */
4914         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4915         0x0000ffff                                                              /* end                      */
4916     };
4917     DWORD shader_code_12_coissue[] =  {
4918         0xffff0102,                                                             /* ps_1_2                   */
4919         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4920         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4921         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4922         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4923         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4924         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4925         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4926         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4927         /* 0x40000000 = D3DSI_COISSUE */
4928         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4929         0x0000ffff                                                              /* end                      */
4930     };
4931     DWORD shader_code_13_coissue[] =  {
4932         0xffff0103,                                                             /* ps_1_3                   */
4933         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
4934         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4935         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
4936         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
4937         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
4938         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
4939         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
4940         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
4941         /* 0x40000000 = D3DSI_COISSUE */
4942         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
4943         0x0000ffff                                                              /* end                      */
4944     };
4945     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4946      * compare against 0.5
4947      */
4948     DWORD shader_code_14_coissue[] =  {
4949         0xffff0104,                                                             /* ps_1_4                   */
4950         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
4951         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
4952         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
4953         /* 0x40000000 = D3DSI_COISSUE */
4954         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
4955         0x0000ffff                                                              /* end                      */
4956     };
4957     float quad1[] = {
4958         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4959          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4960         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4961          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
4962     };
4963     float quad2[] = {
4964          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
4965          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
4966          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
4967          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
4968     };
4969     float quad3[] = {
4970          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4971          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4972          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4973          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
4974     };
4975     float quad4[] = {
4976         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
4977          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
4978         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
4979          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
4980     };
4981     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
4982     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
4983     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
4984     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
4985
4986     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4987     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4988
4989     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4990     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4991     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4992     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4993     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4994     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4995     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4996     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4997     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4998     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4999     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5000     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5001     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5002     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5003     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5004     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5005
5006     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5007     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5008     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5009     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5010     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5011     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5012
5013     hr = IDirect3DDevice9_BeginScene(device);
5014     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5015     if(SUCCEEDED(hr))
5016     {
5017         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5018         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5019         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5020         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5021
5022         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5023         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5024         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5025         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5026
5027         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5028         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5029         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5030         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5031
5032         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5033         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5034         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5035         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5036
5037         hr = IDirect3DDevice9_EndScene(device);
5038         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5039     }
5040
5041     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5042     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5043
5044     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5045     color = getPixelColor(device, 158, 118);
5046     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5047     color = getPixelColor(device, 162, 118);
5048     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5049     color = getPixelColor(device, 158, 122);
5050     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5051     color = getPixelColor(device, 162, 122);
5052     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5053
5054     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5055     color = getPixelColor(device, 158, 358);
5056     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5057     color = getPixelColor(device, 162, 358);
5058     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5059         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5060     color = getPixelColor(device, 158, 362);
5061     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5062     color = getPixelColor(device, 162, 362);
5063     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5064         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5065
5066     /* 1.2 shader */
5067     color = getPixelColor(device, 478, 358);
5068     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5069     color = getPixelColor(device, 482, 358);
5070     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5071         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5072     color = getPixelColor(device, 478, 362);
5073     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5074     color = getPixelColor(device, 482, 362);
5075     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5076         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5077
5078     /* 1.3 shader */
5079     color = getPixelColor(device, 478, 118);
5080     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5081     color = getPixelColor(device, 482, 118);
5082     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5083         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5084     color = getPixelColor(device, 478, 122);
5085     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5086     color = getPixelColor(device, 482, 122);
5087     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5088         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5089
5090     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5091     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5092
5093     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5094     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5095     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5096     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5097     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5098     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5099
5100     hr = IDirect3DDevice9_BeginScene(device);
5101     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5102     if(SUCCEEDED(hr))
5103     {
5104         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5105         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5106         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5107         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5108
5109         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5110         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5111         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5112         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5113
5114         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5115         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5116         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5117         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5118
5119         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5120         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5121         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5122         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5123
5124         hr = IDirect3DDevice9_EndScene(device);
5125         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5126     }
5127
5128     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5129     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5130
5131     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5132      * that we swapped the values in c1 and c2 to make the other tests return some color
5133      */
5134     color = getPixelColor(device, 158, 118);
5135     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5136     color = getPixelColor(device, 162, 118);
5137     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5138     color = getPixelColor(device, 158, 122);
5139     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5140     color = getPixelColor(device, 162, 122);
5141     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5142
5143     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
5144     color = getPixelColor(device, 158, 358);
5145     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5146         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5147     color = getPixelColor(device, 162, 358);
5148     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5149         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5150     color = getPixelColor(device, 158, 362);
5151     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5152         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5153     color = getPixelColor(device, 162, 362);
5154     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5155         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5156
5157     /* 1.2 shader */
5158     color = getPixelColor(device, 478, 358);
5159     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5160         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5161     color = getPixelColor(device, 482, 358);
5162     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5163         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5164     color = getPixelColor(device, 478, 362);
5165     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5166         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5167     color = getPixelColor(device, 482, 362);
5168     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5169         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5170
5171     /* 1.3 shader */
5172     color = getPixelColor(device, 478, 118);
5173     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5174         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5175     color = getPixelColor(device, 482, 118);
5176     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5177         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5178     color = getPixelColor(device, 478, 122);
5179     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5180         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5181     color = getPixelColor(device, 482, 122);
5182     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5183         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5184
5185     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5186     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5187
5188     IDirect3DPixelShader9_Release(shader_14_coissue);
5189     IDirect3DPixelShader9_Release(shader_13_coissue);
5190     IDirect3DPixelShader9_Release(shader_12_coissue);
5191     IDirect3DPixelShader9_Release(shader_11_coissue);
5192     IDirect3DPixelShader9_Release(shader_14);
5193     IDirect3DPixelShader9_Release(shader_13);
5194     IDirect3DPixelShader9_Release(shader_12);
5195     IDirect3DPixelShader9_Release(shader_11);
5196 }
5197
5198 static void nested_loop_test(IDirect3DDevice9 *device) {
5199     const DWORD shader_code[] = {
5200         0xffff0300,                                                             /* ps_3_0               */
5201         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5202         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5203         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5204         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5205         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5206         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5207         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5208         0x0000001d,                                                             /* endloop              */
5209         0x0000001d,                                                             /* endloop              */
5210         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5211         0x0000ffff                                                              /* end                  */
5212     };
5213     IDirect3DPixelShader9 *shader;
5214     HRESULT hr;
5215     DWORD color;
5216     const float quad[] = {
5217         -1.0,   -1.0,   0.1,
5218          1.0,   -1.0,   0.1,
5219         -1.0,    1.0,   0.1,
5220          1.0,    1.0,   0.1
5221     };
5222
5223     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5224     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5225     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5226     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5227     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5228     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5229     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5230     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5231
5232     hr = IDirect3DDevice9_BeginScene(device);
5233     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5234     if(SUCCEEDED(hr))
5235     {
5236         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5237         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5238         hr = IDirect3DDevice9_EndScene(device);
5239         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5240     }
5241
5242     color = getPixelColor(device, 360, 240);
5243     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5244        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5245
5246     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5247     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5248
5249     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5250     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5251     IDirect3DPixelShader9_Release(shader);
5252 }
5253
5254 struct varying_test_struct
5255 {
5256     const DWORD             *shader_code;
5257     IDirect3DPixelShader9   *shader;
5258     DWORD                   color, color_rhw;
5259     const char              *name;
5260     BOOL                    todo, todo_rhw;
5261 };
5262
5263 struct hugeVertex
5264 {
5265     float pos_x,        pos_y,      pos_z,      rhw;
5266     float weight_1,     weight_2,   weight_3,   weight_4;
5267     float index_1,      index_2,    index_3,    index_4;
5268     float normal_1,     normal_2,   normal_3,   normal_4;
5269     float fog_1,        fog_2,      fog_3,      fog_4;
5270     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5271     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5272     float binormal_1,   binormal_2, binormal_3, binormal_4;
5273     float depth_1,      depth_2,    depth_3,    depth_4;
5274     DWORD diffuse, specular;
5275 };
5276
5277 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5278     /* dcl_position: fails to compile */
5279     const DWORD blendweight_code[] = {
5280         0xffff0300,                             /* ps_3_0                   */
5281         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5282         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5283         0x0000ffff                              /* end                      */
5284     };
5285     const DWORD blendindices_code[] = {
5286         0xffff0300,                             /* ps_3_0                   */
5287         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5288         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5289         0x0000ffff                              /* end                      */
5290     };
5291     const DWORD normal_code[] = {
5292         0xffff0300,                             /* ps_3_0                   */
5293         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5294         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5295         0x0000ffff                              /* end                      */
5296     };
5297     /* psize: fails? */
5298     const DWORD texcoord0_code[] = {
5299         0xffff0300,                             /* ps_3_0                   */
5300         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5301         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5302         0x0000ffff                              /* end                      */
5303     };
5304     const DWORD tangent_code[] = {
5305         0xffff0300,                             /* ps_3_0                   */
5306         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5307         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5308         0x0000ffff                              /* end                      */
5309     };
5310     const DWORD binormal_code[] = {
5311         0xffff0300,                             /* ps_3_0                   */
5312         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5313         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5314         0x0000ffff                              /* end                      */
5315     };
5316     /* tessfactor: fails */
5317     /* positiont: fails */
5318     const DWORD color_code[] = {
5319         0xffff0300,                             /* ps_3_0                   */
5320         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5321         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5322         0x0000ffff                              /* end                      */
5323     };
5324     const DWORD fog_code[] = {
5325         0xffff0300,                             /* ps_3_0                   */
5326         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5327         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5328         0x0000ffff                              /* end                      */
5329     };
5330     const DWORD depth_code[] = {
5331         0xffff0300,                             /* ps_3_0                   */
5332         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5333         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5334         0x0000ffff                              /* end                      */
5335     };
5336     const DWORD specular_code[] = {
5337         0xffff0300,                             /* ps_3_0                   */
5338         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5339         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5340         0x0000ffff                              /* end                      */
5341     };
5342     /* sample: fails */
5343
5344     struct varying_test_struct tests[] = {
5345        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5346        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5347        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5348        /* Why does dx not forward the texcoord? */
5349        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5350        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5351        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5352        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5353        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5354        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5355        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5356     };
5357     /* Declare a monster vertex type :-) */
5358     static const D3DVERTEXELEMENT9 decl_elements[] = {
5359         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5360         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5361         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5362         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5363         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5364         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5365         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5366         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5367         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5368         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5369         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5370         D3DDECL_END()
5371     };
5372     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5373         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5374         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5375         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5376         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5377         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5378         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5379         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5380         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5381         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5382         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5383         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5384         D3DDECL_END()
5385     };
5386     struct hugeVertex data[4] = {
5387         {
5388             -1.0,   -1.0,   0.1,    1.0,
5389              0.1,    0.1,   0.1,    0.1,
5390              0.2,    0.2,   0.2,    0.2,
5391              0.3,    0.3,   0.3,    0.3,
5392              0.4,    0.4,   0.4,    0.4,
5393              0.50,   0.55,  0.55,   0.55,
5394              0.6,    0.6,   0.6,    0.7,
5395              0.7,    0.7,   0.7,    0.6,
5396              0.8,    0.8,   0.8,    0.8,
5397              0xe6e6e6e6, /* 0.9 * 256 */
5398              0x224488ff  /* Nothing special */
5399         },
5400         {
5401              1.0,   -1.0,   0.1,    1.0,
5402              0.1,    0.1,   0.1,    0.1,
5403              0.2,    0.2,   0.2,    0.2,
5404              0.3,    0.3,   0.3,    0.3,
5405              0.4,    0.4,   0.4,    0.4,
5406              0.50,   0.55,  0.55,   0.55,
5407              0.6,    0.6,   0.6,    0.7,
5408              0.7,    0.7,   0.7,    0.6,
5409              0.8,    0.8,   0.8,    0.8,
5410              0xe6e6e6e6, /* 0.9 * 256 */
5411              0x224488ff /* Nothing special */
5412         },
5413         {
5414             -1.0,    1.0,   0.1,    1.0,
5415              0.1,    0.1,   0.1,    0.1,
5416              0.2,    0.2,   0.2,    0.2,
5417              0.3,    0.3,   0.3,    0.3,
5418              0.4,    0.4,   0.4,    0.4,
5419              0.50,   0.55,  0.55,   0.55,
5420              0.6,    0.6,   0.6,    0.7,
5421              0.7,    0.7,   0.7,    0.6,
5422              0.8,    0.8,   0.8,    0.8,
5423              0xe6e6e6e6, /* 0.9 * 256 */
5424              0x224488ff /* Nothing special */
5425         },
5426         {
5427              1.0,    1.0,   0.1,    1.0,
5428              0.1,    0.1,   0.1,    0.1,
5429              0.2,    0.2,   0.2,    0.2,
5430              0.3,    0.3,   0.3,    0.3,
5431              0.4,    0.4,   0.4,    0.4,
5432              0.50,   0.55,  0.55,   0.55,
5433              0.6,    0.6,   0.6,    0.7,
5434              0.7,    0.7,   0.7,    0.6,
5435              0.8,    0.8,   0.8,    0.8,
5436              0xe6e6e6e6, /* 0.9 * 256 */
5437              0x224488ff /* Nothing special */
5438         },
5439     };
5440     struct hugeVertex data2[4];
5441     IDirect3DVertexDeclaration9 *decl;
5442     IDirect3DVertexDeclaration9 *decl2;
5443     HRESULT hr;
5444     unsigned int i;
5445     DWORD color, r, g, b, r_e, g_e, b_e;
5446     BOOL drawok;
5447
5448     memcpy(data2, data, sizeof(data2));
5449     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5450     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5451     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5452     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5453
5454     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5455     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5456     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5457     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5458     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5459     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5460
5461     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5462     {
5463         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5464         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5465            tests[i].name, hr);
5466     }
5467
5468     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5469     {
5470         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5471         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5472
5473         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5474         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5475
5476         hr = IDirect3DDevice9_BeginScene(device);
5477         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5478         drawok = FALSE;
5479         if(SUCCEEDED(hr))
5480         {
5481             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5482             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5483             drawok = SUCCEEDED(hr);
5484             hr = IDirect3DDevice9_EndScene(device);
5485             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5486         }
5487
5488         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5489          * the failure and do not check the color if it failed
5490          */
5491         if(!drawok) {
5492             continue;
5493         }
5494
5495         color = getPixelColor(device, 360, 240);
5496         r = color & 0x00ff0000 >> 16;
5497         g = color & 0x0000ff00 >>  8;
5498         b = color & 0x000000ff;
5499         r_e = tests[i].color & 0x00ff0000 >> 16;
5500         g_e = tests[i].color & 0x0000ff00 >>  8;
5501         b_e = tests[i].color & 0x000000ff;
5502
5503         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5504         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5505
5506         if(tests[i].todo) {
5507             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5508                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5509                          tests[i].name, color, tests[i].color);
5510         } else {
5511             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5512                "Test %s returned color 0x%08x, expected 0x%08x\n",
5513                tests[i].name, color, tests[i].color);
5514         }
5515     }
5516
5517     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5518     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5519     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5520     {
5521         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5522         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5523
5524         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5525         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5526
5527         hr = IDirect3DDevice9_BeginScene(device);
5528         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5529         if(SUCCEEDED(hr))
5530         {
5531             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5532             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5533             hr = IDirect3DDevice9_EndScene(device);
5534             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5535         }
5536
5537         color = getPixelColor(device, 360, 240);
5538         r = color & 0x00ff0000 >> 16;
5539         g = color & 0x0000ff00 >>  8;
5540         b = color & 0x000000ff;
5541         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5542         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5543         b_e = tests[i].color_rhw & 0x000000ff;
5544
5545         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5546         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5547
5548         if(tests[i].todo_rhw) {
5549             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5550              * pipeline
5551              */
5552             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5553                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5554                          tests[i].name, color, tests[i].color_rhw);
5555         } else {
5556             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5557                "Test %s returned color 0x%08x, expected 0x%08x\n",
5558                tests[i].name, color, tests[i].color_rhw);
5559         }
5560     }
5561
5562     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5563     {
5564         IDirect3DPixelShader9_Release(tests[i].shader);
5565     }
5566
5567     IDirect3DVertexDeclaration9_Release(decl2);
5568     IDirect3DVertexDeclaration9_Release(decl);
5569 }
5570
5571 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5572     static const DWORD ps_code[] = {
5573     0xffff0300,                                                             /* ps_3_0                       */
5574     0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0          */
5575     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5576     0x0200001f, 0x8001000a, 0x900f0003,                                     /* dcl_color1 v3                */
5577     0x0200001f, 0x8000000b, 0x900f0004,                                     /* dcl_fog v4                   */
5578     0x0200001f, 0x80030005, 0x900f0005,                                     /* dcl_texcoord3 v5             */
5579     0x0200001f, 0x80000003, 0x900f0006,                                     /* dcl_normal v6                */
5580     0x0200001f, 0x80000006, 0x900f0007,                                     /* dcl_tangent v7               */
5581     0x0200001f, 0x80000001, 0x900f0008,                                     /* dcl_blendweight v8           */
5582     0x0200001f, 0x8000000c, 0x900f0009,                                     /* dcl_depth v9                 */
5583
5584     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5585     0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0                  */
5586     0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800,             /* add r0, r0, v0[aL]           */
5587     0x0000001d,                                                             /* endloop                      */
5588     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5589     0x0000ffff                                                              /* end                          */
5590     };
5591     static const DWORD vs_1_code[] = {
5592     0xfffe0101,                                                             /* vs_1_1                       */
5593     0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5594     0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5595     0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5596     0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5597     0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5598     0x00000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5599     0x00000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5600     0x00000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5601     0x00000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5602     0x00000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5603     0x00000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5604     0x00000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5605     0x00000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5606     0x00000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5607     0x00000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5608     0x00000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5609     0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5610     0x0000ffff
5611     };
5612     DWORD vs_2_code[] = {
5613     0xfffe0200,                                                             /* vs_2_0                       */
5614     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5615     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5616     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5617     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5618     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5619     0x02000001, 0xd00f0000, 0xa0e40002,                                     /* mov oD0, c2                  */
5620     0x02000001, 0xd00f0001, 0xa0e40000,                                     /* mov oD1, c0                  */
5621     0x02000001, 0xc00f0001, 0xa0550001,                                     /* mov oFog, c1.g               */
5622     0x02000001, 0xe00f0000, 0xa0e40003,                                     /* mov oT0, c3                  */
5623     0x02000001, 0xe00f0001, 0xa0e40003,                                     /* mov oT1, c3                  */
5624     0x02000001, 0xe00f0002, 0xa0e40003,                                     /* mov oT2, c3                  */
5625     0x02000001, 0xe00f0003, 0xa0e40002,                                     /* mov oT3, c2                  */
5626     0x02000001, 0xe00f0004, 0xa0e40003,                                     /* mov oT4, c3                  */
5627     0x02000001, 0xe00f0005, 0xa0e40003,                                     /* mov oT5, c3                  */
5628     0x02000001, 0xe00f0006, 0xa0e40003,                                     /* mov oT6, c3                  */
5629     0x02000001, 0xe00f0007, 0xa0e40003,                                     /* mov oT7, c3                  */
5630     0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
5631     0x0000ffff                                                              /* end                          */
5632     };
5633     /* TODO: Define normal, tangent, blendweight and depth here */
5634     static const DWORD vs_3_code[] = {
5635     0xfffe0300,                                                             /* vs_3_0                       */
5636     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5637     0x0200001f, 0x8001000a, 0xe00f0009,                                     /* dcl_color1 o9                */
5638     0x0200001f, 0x8000000b, 0xe00f0002,                                     /* dcl_fog o2                   */
5639     0x0200001f, 0x80030005, 0xe00f0005,                                     /* dcl_texcoord3 o5             */
5640     0x0200001f, 0x80000000, 0xe00f000b,                                     /* dcl_position o11             */
5641     0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0   */
5642     0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0   */
5643     0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0   */
5644     0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0   */
5645     0x02000001, 0xe00f0009, 0xa0e40000,                                     /* mov o9, c0                   */
5646     0x02000001, 0xe00f0002, 0xa0e40001,                                     /* mov o2, c1                   */
5647     0x02000001, 0xe00f0005, 0xa0e40002,                                     /* mov o5, c2                   */
5648     0x02000001, 0xe00f000b, 0x90e40000,                                     /* mov o11, v0                  */
5649     0x0000ffff                                                              /* end                          */
5650     };
5651     float quad1[] =  {
5652         -1.0,   -1.0,   0.1,
5653          0.0,   -1.0,   0.1,
5654         -1.0,    0.0,   0.1,
5655          0.0,    0.0,   0.1
5656     };
5657     float quad2[] =  {
5658          0.0,   -1.0,   0.1,
5659          1.0,   -1.0,   0.1,
5660          0.0,    0.0,   0.1,
5661          1.0,    0.0,   0.1
5662     };
5663     float quad3[] =  {
5664         -1.0,    0.0,   0.1,
5665          0.0,    0.0,   0.1,
5666         -1.0,    1.0,   0.1,
5667          0.0,    1.0,   0.1
5668     };
5669
5670     HRESULT hr;
5671     DWORD color;
5672     IDirect3DPixelShader9 *pixelshader = NULL;
5673     IDirect3DVertexShader9 *vs_1_shader = NULL;
5674     IDirect3DVertexShader9 *vs_2_shader = NULL;
5675     IDirect3DVertexShader9 *vs_3_shader = NULL;
5676
5677     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5678     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5679
5680     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5681     ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5682     hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5683     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5684     hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5685     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5686     hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5687     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5688     hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5689     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5690     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5691
5692     hr = IDirect3DDevice9_BeginScene(device);
5693     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5694     if(SUCCEEDED(hr))
5695     {
5696         hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5697         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5698         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5699         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5700
5701         hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5702         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5703         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5704         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5705
5706         hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5707         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5709         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5710
5711         hr = IDirect3DDevice9_EndScene(device);
5712         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5713     }
5714
5715     color = getPixelColor(device, 160, 120);
5716     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5717        "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5718     /* Accept two ways of oFog handling:
5719      *
5720      * oFog is supposed to be a scalar. The pixel shader declares a vec4 oFog input and reads all components.
5721      * The vertex shader writes oFog without a writemask. There are two ways windows drivers deal with this:
5722      *
5723      * 1) Keep oFog a scalar, and assign v4 = {oFog, 0, 0, 0}. oFog = 0x33, so the result color is 004d0067.
5724      *    This happens with software vertex processing and on Intel cards
5725      *
5726      * 2) Make oFog a vec4, and assign v4 = {oFog.x, oFog.y, oFog.z, oFog.w}. This way the result color is
5727      *    0x004d339a. This happens on Nvidia Geforce 6+ cards
5728      */
5729     color = getPixelColor(device, 160, 360);
5730     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5731        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5732        "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5733     color = getPixelColor(device, 480, 360);
5734     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1) ||
5735        color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x33, 0x9a), 1),
5736        "vs_2_0 returned color 0x%08x, expected 0x004d0067 or 0x004d33a0\n", color);
5737
5738     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5739     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5740
5741     /* cleanup */
5742     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5743     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5744     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5745     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5746     if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5747     if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5748     if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5749     if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5750 }
5751
5752 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5753     static const DWORD vs_code[] = {
5754     0xfffe0300,                                                             /* vs_3_0                       */
5755     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
5756     0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0              */
5757     0x0200001f, 0x8000000a, 0xe00f0001,                                     /* dcl_color0 o1                */
5758     0x0200001f, 0x80000005, 0xe00f0002,                                     /* dcl_texcoord0 o2             */
5759     0x0200001f, 0x8000000b, 0xe00f0003,                                     /* dcl_fog o3                   */
5760     0x0200001f, 0x80000003, 0xe00f0004,                                     /* dcl_normal o4                */
5761     0x0200001f, 0x8000000c, 0xe00f0005,                                     /* dcl_depth o5                 */
5762     0x0200001f, 0x80000006, 0xe00f0006,                                     /* dcl_tangent o6               */
5763     0x0200001f, 0x80000001, 0xe00f0007,                                     /* dcl_blendweight o7           */
5764     0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0   */
5765     0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0   */
5766     0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0   */
5767     0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0   */
5768
5769     0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                   */
5770     0x02000001, 0xe00f0001, 0xa0e40001,                                     /* mov o1, c1                   */
5771     0x02000001, 0xe00f0002, 0xa0e40002,                                     /* mov o2, c2                   */
5772     0x02000001, 0xe00f0003, 0xa0e40003,                                     /* mov o3, c3                   */
5773     0x02000001, 0xe00f0004, 0xa0e40000,                                     /* mov o4, c0                   */
5774     0x02000001, 0xe00f0005, 0xa0e40000,                                     /* mov o5, c0                   */
5775     0x02000001, 0xe00f0006, 0xa0e40000,                                     /* mov o6, c0                   */
5776     0x02000001, 0xe00f0007, 0xa0e40000,                                     /* mov o7, c0                   */
5777     0x0000ffff                                                              /* end                          */
5778     };
5779     static const DWORD ps_1_code[] = {
5780     0xffff0104,                                                             /* ps_1_4                       */
5781     0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
5782     0x00000040, 0x80070001, 0xb0e40000,                                     /* texcrd r1.xyz, t0            */
5783     0x00000001, 0x80080001, 0xa0ff0000,                                     /* mov r1.a, c0.a               */
5784     0x00000002, 0x800f0000, 0x90e40000, 0x80e40001,                         /* add r0, v0, r1               */
5785     0x0000ffff                                                              /* end                          */
5786     };
5787     static const DWORD ps_2_code[] = {
5788     0xffff0200,                                                             /* ps_2_0                       */
5789     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
5790     0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl v0                       */
5791     0x0200001f, 0x80000000, 0x900f0001,                                     /* dcl v1                       */
5792
5793     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5794     0x03000002, 0x800f0000, 0x80e40000,0xb0e40000,                          /* add r0, r0, t0               */
5795     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5796     0x0000ffff                                                              /* end                          */
5797     };
5798     static const DWORD ps_3_code[] = {
5799     0xffff0300,                                                             /* ps_3_0                       */
5800     0x0200001f, 0x80000005, 0x900f0000,                                     /* dcl_texcoord0 v0             */
5801     0x0200001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
5802     0x0200001f, 0x8000000b, 0x900f0002,                                     /* dcl_fog v2                   */
5803
5804     0x02000001, 0x800f0000, 0x90e40000,                                     /* mov r0, v0                   */
5805     0x03000002, 0x800f0000, 0x80e40000, 0x90e40001,                         /* add r0, r0, v1               */
5806     0x03000002, 0x800f0000, 0x80e40000, 0x90e40002,                         /* mov r0, r0, v2               */
5807     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5808     0x0000ffff                                                              /* end                          */
5809     };
5810
5811     float quad1[] =  {
5812         -1.0,   -1.0,   0.1,
5813          0.0,   -1.0,   0.1,
5814         -1.0,    0.0,   0.1,
5815          0.0,    0.0,   0.1
5816     };
5817     float quad2[] =  {
5818          0.0,   -1.0,   0.1,
5819          1.0,   -1.0,   0.1,
5820          0.0,    0.0,   0.1,
5821          1.0,    0.0,   0.1
5822     };
5823     float quad3[] =  {
5824         -1.0,    0.0,   0.1,
5825          0.0,    0.0,   0.1,
5826         -1.0,    1.0,   0.1,
5827          0.0,    1.0,   0.1
5828     };
5829     float quad4[] =  {
5830          0.0,    0.0,   0.1,
5831          1.0,    0.0,   0.1,
5832          0.0,    1.0,   0.1,
5833          1.0,    1.0,   0.1
5834     };
5835
5836     HRESULT hr;
5837     DWORD color;
5838     IDirect3DVertexShader9 *vertexshader = NULL;
5839     IDirect3DPixelShader9 *ps_1_shader = NULL;
5840     IDirect3DPixelShader9 *ps_2_shader = NULL;
5841     IDirect3DPixelShader9 *ps_3_shader = NULL;
5842     IDirect3DTexture9 *texture = NULL;
5843     D3DLOCKED_RECT lr;
5844     unsigned int x, y;
5845
5846     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5847     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5848
5849     hr = IDirect3DDevice9_CreateTexture(device, 512,  512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5850     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5851     if(FAILED(hr)) {
5852         skip("D3DFMT_A16B16G16R16 textures not supported\n");
5853         return;
5854     }
5855     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5856     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5857     for(y = 0; y < 512; y++) {
5858         for(x = 0; x < 512; x++) {
5859             double r_f = (double) x / (double) 512;
5860             double g_f = (double) y / (double) 512;
5861             unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5862             unsigned short r = (unsigned short) (r_f * 65535.0);
5863             unsigned short g = (unsigned short) (g_f * 65535.0);
5864             dst[0] = r;
5865             dst[1] = g;
5866             dst[2] = 0;
5867             dst[3] = 65535;
5868         }
5869     }
5870     hr = IDirect3DTexture9_UnlockRect(texture, 0);
5871     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5872
5873     hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5874     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5875     hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5876     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5877     hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5878     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5879     hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5880     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5881     hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5882     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5883     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5884
5885     hr = IDirect3DDevice9_BeginScene(device);
5886     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5887     if(SUCCEEDED(hr))
5888     {
5889         hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5890         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5891         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5892         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5893
5894         hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5895         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5896         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5897         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5898
5899         hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5900         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5901         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5902         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5903
5904         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5905         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5906         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5907         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5908         hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5909         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5910         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5911         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5912         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5913         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5914         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5915         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
5916         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5917         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5918
5919         hr = IDirect3DDevice9_EndScene(device);
5920         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5921     }
5922
5923     color = getPixelColor(device, 160, 120);
5924     ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5925        (color & 0x0000ff00) == 0x0000ff00 &&
5926        (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5927        "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5928     color = getPixelColor(device, 160, 360);
5929     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5930        (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5931        (color & 0x000000ff) == 0x00000000,
5932        "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5933     color = getPixelColor(device, 480, 360);
5934     ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5935        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5936        (color & 0x000000ff) == 0x00000000,
5937        "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5938     color = getPixelColor(device, 480, 160);
5939     ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5940        (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5941        (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5942        (color & 0x000000ff) == 0x00000000),
5943        "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5944
5945     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5946     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5947
5948     /* cleanup */
5949     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5950     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5951     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5952     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5953     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5955     if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5956     if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5957     if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5958     if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5959     if(texture) IDirect3DTexture9_Release(texture);
5960 }
5961
5962 static void test_compare_instructions(IDirect3DDevice9 *device)
5963 {
5964     DWORD shader_sge_vec_code[] = {
5965         0xfffe0101,                                         /* vs_1_1                   */
5966         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5967         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5968         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5969         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5970         0x0000ffff                                          /* end                      */
5971     };
5972     DWORD shader_slt_vec_code[] = {
5973         0xfffe0101,                                         /* vs_1_1                   */
5974         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5975         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5976         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5977         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5978         0x0000ffff                                          /* end                      */
5979     };
5980     DWORD shader_sge_scalar_code[] = {
5981         0xfffe0101,                                         /* vs_1_1                   */
5982         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5983         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5984         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5985         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5986         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5987         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5988         0x0000ffff                                          /* end                      */
5989     };
5990     DWORD shader_slt_scalar_code[] = {
5991         0xfffe0101,                                         /* vs_1_1                   */
5992         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5993         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5994         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5995         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5996         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5997         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5998         0x0000ffff                                          /* end                      */
5999     };
6000     IDirect3DVertexShader9 *shader_sge_vec;
6001     IDirect3DVertexShader9 *shader_slt_vec;
6002     IDirect3DVertexShader9 *shader_sge_scalar;
6003     IDirect3DVertexShader9 *shader_slt_scalar;
6004     HRESULT hr, color;
6005     float quad1[] =  {
6006         -1.0,   -1.0,   0.1,
6007          0.0,   -1.0,   0.1,
6008         -1.0,    0.0,   0.1,
6009          0.0,    0.0,   0.1
6010     };
6011     float quad2[] =  {
6012          0.0,   -1.0,   0.1,
6013          1.0,   -1.0,   0.1,
6014          0.0,    0.0,   0.1,
6015          1.0,    0.0,   0.1
6016     };
6017     float quad3[] =  {
6018         -1.0,    0.0,   0.1,
6019          0.0,    0.0,   0.1,
6020         -1.0,    1.0,   0.1,
6021          0.0,    1.0,   0.1
6022     };
6023     float quad4[] =  {
6024          0.0,    0.0,   0.1,
6025          1.0,    0.0,   0.1,
6026          0.0,    1.0,   0.1,
6027          1.0,    1.0,   0.1
6028     };
6029     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
6030     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
6031
6032     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6033     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6034
6035     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
6036     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6037     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
6038     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6039     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
6040     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6041     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
6042     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6043     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6044     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6045     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
6046     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
6049
6050     hr = IDirect3DDevice9_BeginScene(device);
6051     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6052     if(SUCCEEDED(hr))
6053     {
6054         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
6055         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6056         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
6057         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6058
6059         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
6060         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
6062         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6063
6064         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
6065         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6066         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
6067         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6068
6069         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
6070         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
6071
6072         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
6073         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6074         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
6075         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6076
6077         hr = IDirect3DDevice9_EndScene(device);
6078         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6079     }
6080
6081     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6082     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6083
6084     color = getPixelColor(device, 160, 360);
6085     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
6086     color = getPixelColor(device, 480, 360);
6087     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6088     color = getPixelColor(device, 160, 120);
6089     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6090     color = getPixelColor(device, 480, 160);
6091     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6092
6093     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6094     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6095
6096     IDirect3DVertexShader9_Release(shader_sge_vec);
6097     IDirect3DVertexShader9_Release(shader_slt_vec);
6098     IDirect3DVertexShader9_Release(shader_sge_scalar);
6099     IDirect3DVertexShader9_Release(shader_slt_scalar);
6100 }
6101
6102 static void test_vshader_input(IDirect3DDevice9 *device)
6103 {
6104     DWORD swapped_shader_code_3[] = {
6105         0xfffe0300,                                         /* vs_3_0               */
6106         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6107         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6108         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6109         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6110         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6111         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6112         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6113         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6114         0x0000ffff                                          /* end                  */
6115     };
6116     DWORD swapped_shader_code_1[] = {
6117         0xfffe0101,                                         /* vs_1_1               */
6118         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6119         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6120         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6121         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6122         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6123         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6124         0x0000ffff                                          /* end                  */
6125     };
6126     DWORD swapped_shader_code_2[] = {
6127         0xfffe0200,                                         /* vs_2_0               */
6128         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6129         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6130         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6131         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6132         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6133         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6134         0x0000ffff                                          /* end                  */
6135     };
6136     DWORD texcoord_color_shader_code_3[] = {
6137         0xfffe0300,                                         /* vs_3_0               */
6138         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6139         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6140         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6141         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6142         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6143         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6144         0x0000ffff                                          /* end                  */
6145     };
6146     DWORD texcoord_color_shader_code_2[] = {
6147         0xfffe0200,                                         /* vs_2_0               */
6148         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6149         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6150         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6151         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6152         0x0000ffff                                          /* end                  */
6153     };
6154     DWORD texcoord_color_shader_code_1[] = {
6155         0xfffe0101,                                         /* vs_1_1               */
6156         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6157         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6158         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6159         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6160         0x0000ffff                                          /* end                  */
6161     };
6162     DWORD color_color_shader_code_3[] = {
6163         0xfffe0300,                                         /* vs_3_0               */
6164         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6165         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6166         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6167         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6168         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6169         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6170         0x0000ffff                                          /* end                  */
6171     };
6172     DWORD color_color_shader_code_2[] = {
6173         0xfffe0200,                                         /* vs_2_0               */
6174         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6175         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6176         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6177         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6178         0x0000ffff                                          /* end                  */
6179     };
6180     DWORD color_color_shader_code_1[] = {
6181         0xfffe0101,                                         /* vs_1_1               */
6182         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6183         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6184         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6185         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6186         0x0000ffff                                          /* end                  */
6187     };
6188     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6189     HRESULT hr;
6190     DWORD color;
6191     float quad1[] =  {
6192         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6193          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6194         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6195          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6196     };
6197     float quad2[] =  {
6198          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6199          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6200          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6201          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6202     };
6203     float quad3[] =  {
6204         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6205          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6206         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6207          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6208     };
6209     float quad4[] =  {
6210          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6211          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6212          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6213          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6214     };
6215     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6216         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6217         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6218         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6219         D3DDECL_END()
6220     };
6221     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6222         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6223         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6224         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6225         D3DDECL_END()
6226     };
6227     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6228         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6229         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6230         D3DDECL_END()
6231     };
6232     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6233         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6234         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6235         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6236         D3DDECL_END()
6237     };
6238     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6239         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6240         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6241         D3DDECL_END()
6242     };
6243     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6244         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6245         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6246         D3DDECL_END()
6247     };
6248     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6249         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6250         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6251         D3DDECL_END()
6252     };
6253     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6254         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6255         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6256         D3DDECL_END()
6257     };
6258     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6259     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6260     unsigned int i;
6261     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6262     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6263
6264     struct vertex quad1_color[] =  {
6265        {-1.0,   -1.0,   0.1,    0x00ff8040},
6266        { 0.0,   -1.0,   0.1,    0x00ff8040},
6267        {-1.0,    0.0,   0.1,    0x00ff8040},
6268        { 0.0,    0.0,   0.1,    0x00ff8040}
6269     };
6270     struct vertex quad2_color[] =  {
6271        { 0.0,   -1.0,   0.1,    0x00ff8040},
6272        { 1.0,   -1.0,   0.1,    0x00ff8040},
6273        { 0.0,    0.0,   0.1,    0x00ff8040},
6274        { 1.0,    0.0,   0.1,    0x00ff8040}
6275     };
6276     struct vertex quad3_color[] =  {
6277        {-1.0,    0.0,   0.1,    0x00ff8040},
6278        { 0.0,    0.0,   0.1,    0x00ff8040},
6279        {-1.0,    1.0,   0.1,    0x00ff8040},
6280        { 0.0,    1.0,   0.1,    0x00ff8040}
6281     };
6282     float quad4_color[] =  {
6283          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6284          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6285          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6286          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6287     };
6288
6289     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6290     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6291     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6292     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6293     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6294     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6295     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6296     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6297
6298     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6299     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6300     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6301     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6302     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6303     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6304     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6305     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6306
6307     for(i = 1; i <= 3; i++) {
6308         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6309         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6310         if(i == 3) {
6311             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6312             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6313         } else if(i == 2){
6314             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6315             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6316         } else if(i == 1) {
6317             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6318             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6319         }
6320
6321         hr = IDirect3DDevice9_BeginScene(device);
6322         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6323         if(SUCCEEDED(hr))
6324         {
6325             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6326             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6327
6328             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6329             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6330             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6331             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6332
6333             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6334             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6335             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6336             if(i == 3 || i == 2) {
6337                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6338             } else if(i == 1) {
6339                 /* Succeeds or fails, depending on SW or HW vertex processing */
6340                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6341             }
6342
6343             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6344             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6345             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6346             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6347
6348             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6349             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6350             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6351             if(i == 3 || i == 2) {
6352                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6353             } else if(i == 1) {
6354                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6355             }
6356
6357             hr = IDirect3DDevice9_EndScene(device);
6358             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6359         }
6360
6361         if(i == 3 || i == 2) {
6362             color = getPixelColor(device, 160, 360);
6363             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6364                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6365
6366             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6367             color = getPixelColor(device, 480, 360);
6368             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6369                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6370             color = getPixelColor(device, 160, 120);
6371             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6372             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6373                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6374
6375             color = getPixelColor(device, 480, 160);
6376             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6377         } else if(i == 1) {
6378             color = getPixelColor(device, 160, 360);
6379             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6380                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6381             color = getPixelColor(device, 480, 360);
6382             /* Accept the clear color as well in this case, since SW VP returns an error */
6383             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6384             color = getPixelColor(device, 160, 120);
6385             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6386                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6387             color = getPixelColor(device, 480, 160);
6388             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6389         }
6390
6391         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6392         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6393
6394         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6395         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6396
6397         /* Now find out if the whole streams are re-read, or just the last active value for the
6398          * vertices is used.
6399          */
6400         hr = IDirect3DDevice9_BeginScene(device);
6401         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6402         if(SUCCEEDED(hr))
6403         {
6404             float quad1_modified[] =  {
6405                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6406                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6407                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6408                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6409             };
6410             float quad2_modified[] =  {
6411                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6412                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6413                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6414                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6415             };
6416
6417             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6418             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6419
6420             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6421             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6422             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6423             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6424
6425             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6426             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6427             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6428             if(i == 3 || i == 2) {
6429                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6430             } else if(i == 1) {
6431                 /* Succeeds or fails, depending on SW or HW vertex processing */
6432                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6433             }
6434
6435             hr = IDirect3DDevice9_EndScene(device);
6436             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6437         }
6438
6439         color = getPixelColor(device, 480, 350);
6440         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6441          * as well.
6442          *
6443          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6444          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6445          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6446          * refrast's result.
6447          *
6448          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6449          */
6450         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6451            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6452
6453         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6454         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6455
6456         IDirect3DDevice9_SetVertexShader(device, NULL);
6457         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6458
6459         IDirect3DVertexShader9_Release(swapped_shader);
6460     }
6461
6462     for(i = 1; i <= 3; i++) {
6463         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6464         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6465         if(i == 3) {
6466             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6467             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6468             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6469             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6470         } else if(i == 2){
6471             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6472             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6473             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6474             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6475         } else if(i == 1) {
6476             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6477             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6478             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6479             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6480         }
6481
6482         hr = IDirect3DDevice9_BeginScene(device);
6483         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6484         if(SUCCEEDED(hr))
6485         {
6486             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6487             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6488             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6489             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6490             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6491             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6492
6493             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6494             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6495
6496             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6497             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6498             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6499             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6500             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6501             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6502
6503             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6504             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6505             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6506             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6507             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6508             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6509
6510             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6511             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6512             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6513             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6514
6515             hr = IDirect3DDevice9_EndScene(device);
6516             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6517         }
6518         IDirect3DDevice9_SetVertexShader(device, NULL);
6519         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6520
6521         color = getPixelColor(device, 160, 360);
6522         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6523            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6524         color = getPixelColor(device, 480, 360);
6525         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6526            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6527         color = getPixelColor(device, 160, 120);
6528         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6529            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6530         color = getPixelColor(device, 480, 160);
6531         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6532            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6533
6534         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6535         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6536
6537         IDirect3DVertexShader9_Release(texcoord_color_shader);
6538         IDirect3DVertexShader9_Release(color_color_shader);
6539     }
6540
6541     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6542     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6543     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6544     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6545
6546     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6547     IDirect3DVertexDeclaration9_Release(decl_color_color);
6548     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6549     IDirect3DVertexDeclaration9_Release(decl_color_float);
6550 }
6551
6552 static void srgbtexture_test(IDirect3DDevice9 *device)
6553 {
6554     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6555      * texture stage state to render a quad using that texture.  The resulting
6556      * color components should be 0x36 (~ 0.21), per this formula:
6557      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6558      * This is true where srgb_color > 0.04045.
6559      */
6560     IDirect3D9 *d3d = NULL;
6561     HRESULT hr;
6562     LPDIRECT3DTEXTURE9 texture = NULL;
6563     LPDIRECT3DSURFACE9 surface = NULL;
6564     D3DLOCKED_RECT lr;
6565     DWORD color;
6566     float quad[] = {
6567         -1.0,       1.0,       0.0,     0.0,    0.0,
6568          1.0,       1.0,       0.0,     1.0,    0.0,
6569         -1.0,      -1.0,       0.0,     0.0,    1.0,
6570          1.0,      -1.0,       0.0,     1.0,    1.0,
6571     };
6572
6573
6574     memset(&lr, 0, sizeof(lr));
6575     IDirect3DDevice9_GetDirect3D(device, &d3d);
6576     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6577                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6578                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6579         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6580         goto out;
6581     }
6582
6583     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6584                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6585                                         &texture, NULL);
6586     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6587     if(!texture) {
6588         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6589         goto out;
6590     }
6591     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6592     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6593
6594     fill_surface(surface, 0xff7f7f7f);
6595     IDirect3DSurface9_Release(surface);
6596
6597     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6598     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6599     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6600     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6601
6602     hr = IDirect3DDevice9_BeginScene(device);
6603     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6604     if(SUCCEEDED(hr))
6605     {
6606         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6607         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6608
6609         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6610         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6611
6612
6613         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6614         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6615
6616         hr = IDirect3DDevice9_EndScene(device);
6617         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6618     }
6619
6620     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6621     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6622     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6623     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6624
6625     color = getPixelColor(device, 320, 240);
6626     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6627
6628     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6629     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6630
6631 out:
6632     if(texture) IDirect3DTexture9_Release(texture);
6633     IDirect3D9_Release(d3d);
6634 }
6635
6636 static void shademode_test(IDirect3DDevice9 *device)
6637 {
6638     /* Render a quad and try all of the different fixed function shading models. */
6639     HRESULT hr;
6640     DWORD color0, color1;
6641     DWORD color0_gouraud = 0, color1_gouraud = 0;
6642     DWORD shademode = D3DSHADE_FLAT;
6643     DWORD primtype = D3DPT_TRIANGLESTRIP;
6644     LPVOID data = NULL;
6645     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6646     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6647     UINT i, j;
6648     struct vertex quad_strip[] =
6649     {
6650         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6651         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6652         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6653         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6654     };
6655     struct vertex quad_list[] =
6656     {
6657         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6658         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6659         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6660
6661         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6662         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6663         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6664     };
6665
6666     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6667                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6668     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6669     if (FAILED(hr)) goto bail;
6670
6671     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6672                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6673     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6674     if (FAILED(hr)) goto bail;
6675
6676     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6677     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6678
6679     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6680     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6681
6682     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6683     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6684     memcpy(data, quad_strip, sizeof(quad_strip));
6685     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6686     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6687
6688     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6689     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6690     memcpy(data, quad_list, sizeof(quad_list));
6691     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6692     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6693
6694     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6695      * the color fixups we have to do for FLAT shading will be dependent on that. */
6696     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6697     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6698
6699     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6700     for (j=0; j<2; j++) {
6701
6702         /* Inner loop just changes the D3DRS_SHADEMODE */
6703         for (i=0; i<3; i++) {
6704             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6705             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6706
6707             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6708             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6709
6710             hr = IDirect3DDevice9_BeginScene(device);
6711             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6712             if(SUCCEEDED(hr))
6713             {
6714                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6715                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6716
6717                 hr = IDirect3DDevice9_EndScene(device);
6718                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6719             }
6720
6721             /* Sample two spots from the output */
6722             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6723             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6724             switch(shademode) {
6725                 case D3DSHADE_FLAT:
6726                     /* Should take the color of the first vertex of each triangle */
6727                     if (0)
6728                     {
6729                         /* This test depends on EXT_provoking_vertex being
6730                          * available. This extension is currently (20090810)
6731                          * not common enough to let the test fail if it isn't
6732                          * present. */
6733                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6734                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6735                     }
6736                     shademode = D3DSHADE_GOURAUD;
6737                     break;
6738                 case D3DSHADE_GOURAUD:
6739                     /* Should be an interpolated blend */
6740
6741                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6742                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6743                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6744                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6745
6746                     color0_gouraud = color0;
6747                     color1_gouraud = color1;
6748
6749                     shademode = D3DSHADE_PHONG;
6750                     break;
6751                 case D3DSHADE_PHONG:
6752                     /* Should be the same as GOURAUD, since no hardware implements this */
6753                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6754                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6755                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6756                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6757
6758                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6759                             color0_gouraud, color0);
6760                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6761                             color1_gouraud, color1);
6762                     break;
6763             }
6764         }
6765
6766         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6767         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6768
6769         /* Now, do it all over again with a TRIANGLELIST */
6770         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6771         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6772         primtype = D3DPT_TRIANGLELIST;
6773         shademode = D3DSHADE_FLAT;
6774     }
6775
6776 bail:
6777     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6778     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6779     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6780     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6781
6782     if (vb_strip)
6783         IDirect3DVertexBuffer9_Release(vb_strip);
6784     if (vb_list)
6785         IDirect3DVertexBuffer9_Release(vb_list);
6786 }
6787
6788
6789 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6790 {
6791     /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6792      * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6793      * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6794      * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6795      * 0.73
6796      *
6797      * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6798      * so use shaders for this task
6799      */
6800     IDirect3DPixelShader9 *pshader;
6801     IDirect3DVertexShader9 *vshader;
6802     IDirect3D9 *d3d;
6803     DWORD vshader_code[] = {
6804         0xfffe0101,                                                             /* vs_1_1                       */
6805         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
6806         0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0   */
6807         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
6808         0x00000001, 0xc00f0001, 0xa0000000,                                     /* mov oFog, c0.x               */
6809         0x0000ffff                                                              /* end                          */
6810     };
6811     DWORD pshader_code[] = {
6812         0xffff0101,                                                             /* ps_1_1                       */
6813         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0   */
6814         0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
6815         0x0000ffff                                                              /* end                          */
6816     };
6817     const float quad[] = {
6818        -1.0,   -1.0,    0.1,
6819         1.0,   -1.0,    0.1,
6820        -1.0,    1.0,    0.1,
6821         1.0,    1.0,    0.1
6822     };
6823     HRESULT hr;
6824     D3DCOLOR color;
6825
6826     IDirect3DDevice9_GetDirect3D(device, &d3d);
6827     /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6828      * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6829      * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6830      * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6831      * works
6832      */
6833     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6834                                     D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6835                                     D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6836         skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6837         IDirect3D9_Release(d3d);
6838         return;
6839     }
6840     IDirect3D9_Release(d3d);
6841
6842     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6843     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6844
6845     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6846     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6847     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6848     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6849     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6850     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6851     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6852     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6853     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6854     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6855
6856     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6857     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6858     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6859     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6860     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6861     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6862     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6863     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6864     hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6865     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6866
6867     hr = IDirect3DDevice9_BeginScene(device);
6868     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6869     if(SUCCEEDED(hr)) {
6870         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6871         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6872
6873         hr = IDirect3DDevice9_EndScene(device);
6874         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6875     }
6876
6877     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6878     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6879     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6880     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6881     IDirect3DPixelShader9_Release(pshader);
6882     IDirect3DVertexShader9_Release(vshader);
6883
6884     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6885     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6886     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6887     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6888
6889     color = getPixelColor(device, 160, 360);
6890     ok(color_match(color, 0x00808080, 1),
6891             "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6892     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6893     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6894 }
6895
6896 static void alpha_test(IDirect3DDevice9 *device)
6897 {
6898     HRESULT hr;
6899     IDirect3DTexture9 *offscreenTexture;
6900     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6901     DWORD color;
6902
6903     struct vertex quad1[] =
6904     {
6905         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6906         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6907         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6908         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6909     };
6910     struct vertex quad2[] =
6911     {
6912         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6913         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6914         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6915         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6916     };
6917     static const float composite_quad[][5] = {
6918         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6919         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6920         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6921         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6922     };
6923
6924     /* Clear the render target with alpha = 0.5 */
6925     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6926     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6927
6928     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6929     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6930
6931     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6932     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6933     if(!backbuffer) {
6934         goto out;
6935     }
6936
6937     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6938     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6939     if(!offscreen) {
6940         goto out;
6941     }
6942
6943     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6944     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6945
6946     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6947     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6948     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6949     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6950     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6951     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6952     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6953     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6954     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6955     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6956
6957     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6958     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6959     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6960
6961         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6962         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6963         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6964         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6965         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6966         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6967         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6968
6969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6970         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6971         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6972         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6973         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6974         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6975
6976         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6977          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6978          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6979         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6980         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6981         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6982         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6983
6984         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6985         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6986         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6987         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6988         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6989         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6990
6991         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6992         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6993         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6994         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6995         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6996         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6997
6998         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6999         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
7000
7001         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
7002          * Disable alpha blending for the final composition
7003          */
7004         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
7005         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
7006         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7007         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
7008
7009         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
7010         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7011         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
7012         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7013         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7014         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
7015
7016         hr = IDirect3DDevice9_EndScene(device);
7017         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
7018     }
7019
7020     color = getPixelColor(device, 160, 360);
7021     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7022        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
7023
7024     color = getPixelColor(device, 160, 120);
7025     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
7026        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
7027
7028     color = getPixelColor(device, 480, 360);
7029     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
7030        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
7031
7032     color = getPixelColor(device, 480, 120);
7033     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
7034        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
7035
7036     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7037
7038     out:
7039     /* restore things */
7040     if(backbuffer) {
7041         IDirect3DSurface9_Release(backbuffer);
7042     }
7043     if(offscreenTexture) {
7044         IDirect3DTexture9_Release(offscreenTexture);
7045     }
7046     if(offscreen) {
7047         IDirect3DSurface9_Release(offscreen);
7048     }
7049 }
7050
7051 struct vertex_shortcolor {
7052     float x, y, z;
7053     unsigned short r, g, b, a;
7054 };
7055 struct vertex_floatcolor {
7056     float x, y, z;
7057     float r, g, b, a;
7058 };
7059
7060 static void fixed_function_decl_test(IDirect3DDevice9 *device)
7061 {
7062     HRESULT hr;
7063     BOOL s_ok, ub_ok, f_ok;
7064     DWORD color, size, i;
7065     void *data;
7066     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
7067         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7068         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7069         D3DDECL_END()
7070     };
7071     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
7072         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7073         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7074         D3DDECL_END()
7075     };
7076     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
7077         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7078         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7079         D3DDECL_END()
7080     };
7081     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
7082         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7083         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7084         D3DDECL_END()
7085     };
7086     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
7087         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7088         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7089         D3DDECL_END()
7090     };
7091     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
7092         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7093         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7094         D3DDECL_END()
7095     };
7096     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
7097         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
7098         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7099         D3DDECL_END()
7100     };
7101     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
7102     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
7103     IDirect3DVertexBuffer9 *vb, *vb2;
7104     struct vertex quad1[] =                             /* D3DCOLOR */
7105     {
7106         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
7107         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7108         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
7109         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7110     };
7111     struct vertex quad2[] =                             /* UBYTE4N */
7112     {
7113         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
7114         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
7115         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
7116         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
7117     };
7118     struct vertex_shortcolor quad3[] =                  /* short */
7119     {
7120         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7121         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7122         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7123         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
7124     };
7125     struct vertex_floatcolor quad4[] =
7126     {
7127         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7128         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7129         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7130         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
7131     };
7132     DWORD colors[] = {
7133         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7134         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7135         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7136         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7137         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7138         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7139         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7140         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7141         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7142         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7143         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7144         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7145         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7146         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7147         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7148         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
7149     };
7150     float quads[] = {
7151         -1.0,   -1.0,     0.1,
7152         -1.0,    0.0,     0.1,
7153          0.0,   -1.0,     0.1,
7154          0.0,    0.0,     0.1,
7155
7156          0.0,   -1.0,     0.1,
7157          0.0,    0.0,     0.1,
7158          1.0,   -1.0,     0.1,
7159          1.0,    0.0,     0.1,
7160
7161          0.0,    0.0,     0.1,
7162          0.0,    1.0,     0.1,
7163          1.0,    0.0,     0.1,
7164          1.0,    1.0,     0.1,
7165
7166         -1.0,    0.0,     0.1,
7167         -1.0,    1.0,     0.1,
7168          0.0,    0.0,     0.1,
7169          0.0,    1.0,     0.1
7170     };
7171     struct tvertex quad_transformed[] = {
7172        {  90,    110,     0.1,      2.0,        0x00ffff00},
7173        { 570,    110,     0.1,      2.0,        0x00ffff00},
7174        {  90,    300,     0.1,      2.0,        0x00ffff00},
7175        { 570,    300,     0.1,      2.0,        0x00ffff00}
7176     };
7177     D3DCAPS9 caps;
7178
7179     memset(&caps, 0, sizeof(caps));
7180     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7181     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
7182
7183     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7184     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
7185
7186     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
7187     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7188     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
7189     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
7190     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
7191     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7192     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
7193         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
7194         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7195         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7196         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7197     } else {
7198         trace("D3DDTCAPS_UBYTE4N not supported\n");
7199         dcl_ubyte_2 = NULL;
7200         dcl_ubyte = NULL;
7201     }
7202     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7203     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7204     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7205     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7206
7207     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7208     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7209                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7210     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7211
7212     hr = IDirect3DDevice9_BeginScene(device);
7213     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7214     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7215     if(SUCCEEDED(hr)) {
7216         if(dcl_color) {
7217             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7218             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7219             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7220             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7221         }
7222
7223         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7224          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7225          * using software vertex processing. Doh!
7226          */
7227         if(dcl_ubyte) {
7228             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7229             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7230             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7231             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7232             ub_ok = SUCCEEDED(hr);
7233         }
7234
7235         if(dcl_short) {
7236             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7237             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7238             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7239             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7240             s_ok = SUCCEEDED(hr);
7241         }
7242
7243         if(dcl_float) {
7244             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7245             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7246             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7247             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7248             f_ok = SUCCEEDED(hr);
7249         }
7250
7251         hr = IDirect3DDevice9_EndScene(device);
7252         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7253     }
7254
7255     if(dcl_short) {
7256         color = getPixelColor(device, 480, 360);
7257         ok(color == 0x000000ff || !s_ok,
7258            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7259     }
7260     if(dcl_ubyte) {
7261         color = getPixelColor(device, 160, 120);
7262         ok(color == 0x0000ffff || !ub_ok,
7263            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7264     }
7265     if(dcl_color) {
7266         color = getPixelColor(device, 160, 360);
7267         ok(color == 0x00ffff00,
7268            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7269     }
7270     if(dcl_float) {
7271         color = getPixelColor(device, 480, 120);
7272         ok(color == 0x00ff0000 || !f_ok,
7273            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7274     }
7275     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7276
7277     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7278      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7279      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7280      * whether the immediate mode code works
7281      */
7282     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7283     hr = IDirect3DDevice9_BeginScene(device);
7284     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7285     if(SUCCEEDED(hr)) {
7286         if(dcl_color) {
7287             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7288             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7289             memcpy(data, quad1, sizeof(quad1));
7290             hr = IDirect3DVertexBuffer9_Unlock(vb);
7291             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7292             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7293             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7294             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7295             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7296             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7297             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7298         }
7299
7300         if(dcl_ubyte) {
7301             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7302             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7303             memcpy(data, quad2, sizeof(quad2));
7304             hr = IDirect3DVertexBuffer9_Unlock(vb);
7305             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7306             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7307             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7308             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7309             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7310             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7311             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7312                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7313             ub_ok = SUCCEEDED(hr);
7314         }
7315
7316         if(dcl_short) {
7317             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7318             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7319             memcpy(data, quad3, sizeof(quad3));
7320             hr = IDirect3DVertexBuffer9_Unlock(vb);
7321             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7322             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7323             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7324             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7325             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7326             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7327             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7328                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7329             s_ok = SUCCEEDED(hr);
7330         }
7331
7332         if(dcl_float) {
7333             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7334             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7335             memcpy(data, quad4, sizeof(quad4));
7336             hr = IDirect3DVertexBuffer9_Unlock(vb);
7337             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7338             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7339             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7340             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7341             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7342             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7343             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7344                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7345             f_ok = SUCCEEDED(hr);
7346         }
7347
7348         hr = IDirect3DDevice9_EndScene(device);
7349         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7350     }
7351
7352     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7353     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7354     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7355     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7356
7357     if(dcl_short) {
7358         color = getPixelColor(device, 480, 360);
7359         ok(color == 0x000000ff || !s_ok,
7360            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7361     }
7362     if(dcl_ubyte) {
7363         color = getPixelColor(device, 160, 120);
7364         ok(color == 0x0000ffff || !ub_ok,
7365            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7366     }
7367     if(dcl_color) {
7368         color = getPixelColor(device, 160, 360);
7369         ok(color == 0x00ffff00,
7370            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7371     }
7372     if(dcl_float) {
7373         color = getPixelColor(device, 480, 120);
7374         ok(color == 0x00ff0000 || !f_ok,
7375            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7376     }
7377     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7378
7379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7380     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7381
7382     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7383     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7384     memcpy(data, quad_transformed, sizeof(quad_transformed));
7385     hr = IDirect3DVertexBuffer9_Unlock(vb);
7386     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7387
7388     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7389     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7390
7391     hr = IDirect3DDevice9_BeginScene(device);
7392     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7393     if(SUCCEEDED(hr)) {
7394         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7395         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7396         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7397         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7398
7399         hr = IDirect3DDevice9_EndScene(device);
7400         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7401     }
7402
7403     color = getPixelColor(device, 88, 108);
7404     ok(color == 0x000000ff,
7405        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7406     color = getPixelColor(device, 92, 108);
7407     ok(color == 0x000000ff,
7408        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7409     color = getPixelColor(device, 88, 112);
7410     ok(color == 0x000000ff,
7411        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7412     color = getPixelColor(device, 92, 112);
7413     ok(color == 0x00ffff00,
7414        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7415
7416     color = getPixelColor(device, 568, 108);
7417     ok(color == 0x000000ff,
7418        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7419     color = getPixelColor(device, 572, 108);
7420     ok(color == 0x000000ff,
7421        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7422     color = getPixelColor(device, 568, 112);
7423     ok(color == 0x00ffff00,
7424        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7425     color = getPixelColor(device, 572, 112);
7426     ok(color == 0x000000ff,
7427        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7428
7429     color = getPixelColor(device, 88, 298);
7430     ok(color == 0x000000ff,
7431        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7432     color = getPixelColor(device, 92, 298);
7433     ok(color == 0x00ffff00,
7434        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7435     color = getPixelColor(device, 88, 302);
7436     ok(color == 0x000000ff,
7437        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7438     color = getPixelColor(device, 92, 302);
7439     ok(color == 0x000000ff,
7440        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7441
7442     color = getPixelColor(device, 568, 298);
7443     ok(color == 0x00ffff00,
7444        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7445     color = getPixelColor(device, 572, 298);
7446     ok(color == 0x000000ff,
7447        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7448     color = getPixelColor(device, 568, 302);
7449     ok(color == 0x000000ff,
7450        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7451     color = getPixelColor(device, 572, 302);
7452     ok(color == 0x000000ff,
7453        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7454
7455     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7456
7457     /* This test is pointless without those two declarations: */
7458     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7459         skip("color-ubyte switching test declarations aren't supported\n");
7460         goto out;
7461     }
7462
7463     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7464     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7465     memcpy(data, quads, sizeof(quads));
7466     hr = IDirect3DVertexBuffer9_Unlock(vb);
7467     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7468     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7469                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7470     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7471     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7472     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7473     memcpy(data, colors, sizeof(colors));
7474     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7475     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7476
7477     for(i = 0; i < 2; i++) {
7478         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7479         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7480
7481         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7482         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7483         if(i == 0) {
7484             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7485         } else {
7486             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7487         }
7488         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7489
7490         hr = IDirect3DDevice9_BeginScene(device);
7491         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7492         ub_ok = FALSE;
7493         if(SUCCEEDED(hr)) {
7494             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7495             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7496             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7497             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7498                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7499             ub_ok = SUCCEEDED(hr);
7500
7501             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7502             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7503             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7504             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7505
7506             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7507             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7508             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7509             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7510                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7511             ub_ok = (SUCCEEDED(hr) && ub_ok);
7512
7513             hr = IDirect3DDevice9_EndScene(device);
7514             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7515         }
7516
7517         if(i == 0) {
7518             color = getPixelColor(device, 480, 360);
7519             ok(color == 0x00ff0000,
7520                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7521             color = getPixelColor(device, 160, 120);
7522             ok(color == 0x00ffffff,
7523                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7524             color = getPixelColor(device, 160, 360);
7525             ok(color == 0x000000ff || !ub_ok,
7526                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7527             color = getPixelColor(device, 480, 120);
7528             ok(color == 0x000000ff || !ub_ok,
7529                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7530         } else {
7531             color = getPixelColor(device, 480, 360);
7532             ok(color == 0x000000ff,
7533                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7534             color = getPixelColor(device, 160, 120);
7535             ok(color == 0x00ffffff,
7536                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7537             color = getPixelColor(device, 160, 360);
7538             ok(color == 0x00ff0000 || !ub_ok,
7539                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7540             color = getPixelColor(device, 480, 120);
7541             ok(color == 0x00ff0000 || !ub_ok,
7542                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7543         }
7544         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7545     }
7546
7547     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7548     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7549     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7550     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7551     IDirect3DVertexBuffer9_Release(vb2);
7552
7553     out:
7554     IDirect3DVertexBuffer9_Release(vb);
7555     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7556     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7557     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7558     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7559     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7560     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7561     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7562 }
7563
7564 struct vertex_float16color {
7565     float x, y, z;
7566     DWORD c1, c2;
7567 };
7568
7569 static void test_vshader_float16(IDirect3DDevice9 *device)
7570 {
7571     HRESULT hr;
7572     DWORD color;
7573     void *data;
7574     static const D3DVERTEXELEMENT9 decl_elements[] = {
7575         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7576         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7577         D3DDECL_END()
7578     };
7579     IDirect3DVertexDeclaration9 *vdecl = NULL;
7580     IDirect3DVertexBuffer9 *buffer = NULL;
7581     IDirect3DVertexShader9 *shader;
7582     DWORD shader_code[] = {
7583         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7584         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7585         0x90e40001, 0x0000ffff
7586     };
7587     struct vertex_float16color quad[] = {
7588         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7589         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7590         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7591         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7592
7593         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7594         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7595         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7596         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7597
7598         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7599         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7600         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7601         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7602
7603         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7604         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7605         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7606         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7607     };
7608
7609     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7610     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7611
7612     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7613     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7614     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7615     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7616     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7617     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7618
7619     hr = IDirect3DDevice9_BeginScene(device);
7620     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7621     if(SUCCEEDED(hr)) {
7622         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7623         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7624         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7625         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7627         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7628         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7629         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7630         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7631         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7632
7633         hr = IDirect3DDevice9_EndScene(device);
7634         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7635     }
7636     color = getPixelColor(device, 480, 360);
7637     ok(color == 0x00ff0000,
7638        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7639     color = getPixelColor(device, 160, 120);
7640     ok(color == 0x00000000,
7641        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7642     color = getPixelColor(device, 160, 360);
7643     ok(color == 0x0000ff00,
7644        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7645     color = getPixelColor(device, 480, 120);
7646     ok(color == 0x000000ff,
7647        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7648     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7649
7650     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7651     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7652
7653     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7654                                              D3DPOOL_MANAGED, &buffer, NULL);
7655     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7656     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7657     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7658     memcpy(data, quad, sizeof(quad));
7659     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7660     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7661     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7662     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7663
7664     hr = IDirect3DDevice9_BeginScene(device);
7665     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7666     if(SUCCEEDED(hr)) {
7667             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7668             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7669             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7670             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7671             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7672             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7673             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7674             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7675
7676             hr = IDirect3DDevice9_EndScene(device);
7677             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7678     }
7679
7680     color = getPixelColor(device, 480, 360);
7681     ok(color == 0x00ff0000,
7682        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7683     color = getPixelColor(device, 160, 120);
7684     ok(color == 0x00000000,
7685        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7686     color = getPixelColor(device, 160, 360);
7687     ok(color == 0x0000ff00,
7688        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7689     color = getPixelColor(device, 480, 120);
7690     ok(color == 0x000000ff,
7691        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7692     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7693
7694     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7695     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7696     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7697     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7698     IDirect3DDevice9_SetVertexShader(device, NULL);
7699     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7700
7701     IDirect3DVertexDeclaration9_Release(vdecl);
7702     IDirect3DVertexShader9_Release(shader);
7703     IDirect3DVertexBuffer9_Release(buffer);
7704 }
7705
7706 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7707 {
7708     D3DCAPS9 caps;
7709     IDirect3DTexture9 *texture;
7710     HRESULT hr;
7711     D3DLOCKED_RECT rect;
7712     unsigned int x, y;
7713     DWORD *dst, color;
7714     const float quad[] = {
7715         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7716          1.0,   -1.0,   0.1,    1.2,   -0.2,
7717         -1.0,    1.0,   0.1,   -0.2,    1.2,
7718          1.0,    1.0,   0.1,    1.2,    1.2
7719     };
7720     memset(&caps, 0, sizeof(caps));
7721
7722     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7723     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7724     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7725         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7726         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7727            "Card has conditional NP2 support without power of two restriction set\n");
7728         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7729         return;
7730     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7731         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7732         return;
7733     }
7734
7735     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7736     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7737
7738     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7739     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7740
7741     memset(&rect, 0, sizeof(rect));
7742     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7743     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7744     for(y = 0; y < 10; y++) {
7745         for(x = 0; x < 10; x++) {
7746             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7747             if(x == 0 || x == 9 || y == 0 || y == 9) {
7748                 *dst = 0x00ff0000;
7749             } else {
7750                 *dst = 0x000000ff;
7751             }
7752         }
7753     }
7754     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7755     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7756
7757     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7758     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7759     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7760     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7761     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7762     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7763     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7764     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7765
7766     hr = IDirect3DDevice9_BeginScene(device);
7767     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7768     if(SUCCEEDED(hr)) {
7769         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7770         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7771
7772         hr = IDirect3DDevice9_EndScene(device);
7773         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7774     }
7775
7776     color = getPixelColor(device,    1,  1);
7777     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7778     color = getPixelColor(device, 639, 479);
7779     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7780
7781     color = getPixelColor(device, 135, 101);
7782     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7783     color = getPixelColor(device, 140, 101);
7784     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7785     color = getPixelColor(device, 135, 105);
7786     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7787     color = getPixelColor(device, 140, 105);
7788     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7789
7790     color = getPixelColor(device, 135, 376);
7791     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7792     color = getPixelColor(device, 140, 376);
7793     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7794     color = getPixelColor(device, 135, 379);
7795     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7796     color = getPixelColor(device, 140, 379);
7797     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7798
7799     color = getPixelColor(device, 500, 101);
7800     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7801     color = getPixelColor(device, 504, 101);
7802     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7803     color = getPixelColor(device, 500, 105);
7804     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7805     color = getPixelColor(device, 504, 105);
7806     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7807
7808     color = getPixelColor(device, 500, 376);
7809     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7810     color = getPixelColor(device, 504, 376);
7811     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7812     color = getPixelColor(device, 500, 380);
7813     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7814     color = getPixelColor(device, 504, 380);
7815     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7816
7817     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7818
7819     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7820     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7821     IDirect3DTexture9_Release(texture);
7822 }
7823
7824 static void vFace_register_test(IDirect3DDevice9 *device)
7825 {
7826     HRESULT hr;
7827     DWORD color;
7828     const DWORD shader_code[] = {
7829         0xffff0300,                                                             /* ps_3_0                     */
7830         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7831         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7832         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7833         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7834         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7835         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7836         0x0000ffff                                                              /* END                        */
7837     };
7838     IDirect3DPixelShader9 *shader;
7839     IDirect3DTexture9 *texture;
7840     IDirect3DSurface9 *surface, *backbuffer;
7841     const float quad[] = {
7842         -1.0,   -1.0,   0.1,
7843          1.0,   -1.0,   0.1,
7844         -1.0,    0.0,   0.1,
7845
7846          1.0,   -1.0,   0.1,
7847          1.0,    0.0,   0.1,
7848         -1.0,    0.0,   0.1,
7849
7850         -1.0,    0.0,   0.1,
7851         -1.0,    1.0,   0.1,
7852          1.0,    0.0,   0.1,
7853
7854          1.0,    0.0,   0.1,
7855         -1.0,    1.0,   0.1,
7856          1.0,    1.0,   0.1,
7857     };
7858     const float blit[] = {
7859          0.0,   -1.0,   0.1,    0.0,    0.0,
7860          1.0,   -1.0,   0.1,    1.0,    0.0,
7861          0.0,    1.0,   0.1,    0.0,    1.0,
7862          1.0,    1.0,   0.1,    1.0,    1.0,
7863     };
7864
7865     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7866     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7867     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7868     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7869     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7870     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7871     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7872     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7873     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7874     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7875     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7876     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7877
7878     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7879     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7880
7881     hr = IDirect3DDevice9_BeginScene(device);
7882     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7883     if(SUCCEEDED(hr)) {
7884         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7885         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7886         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7887         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7888         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7889         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7890         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7891         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7892         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7893         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7894         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7895
7896         /* Blit the texture onto the back buffer to make it visible */
7897         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7898         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7899         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7900         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7901         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7902         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7903         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7904         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7905         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7906         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7907
7908         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7909         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7910
7911         hr = IDirect3DDevice9_EndScene(device);
7912         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7913     }
7914
7915     color = getPixelColor(device, 160, 360);
7916     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7917     color = getPixelColor(device, 160, 120);
7918     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7919     color = getPixelColor(device, 480, 360);
7920     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7921     color = getPixelColor(device, 480, 120);
7922     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7923     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7924
7925     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7926     IDirect3DDevice9_SetTexture(device, 0, NULL);
7927     IDirect3DPixelShader9_Release(shader);
7928     IDirect3DSurface9_Release(surface);
7929     IDirect3DSurface9_Release(backbuffer);
7930     IDirect3DTexture9_Release(texture);
7931 }
7932
7933 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7934 {
7935     HRESULT hr;
7936     DWORD color;
7937     int i;
7938     D3DCAPS9 caps;
7939     BOOL L6V5U5_supported = FALSE;
7940     IDirect3DTexture9 *tex1, *tex2;
7941     D3DLOCKED_RECT locked_rect;
7942
7943     static const float quad[][7] = {
7944         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7945         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7946         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7947         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7948     };
7949
7950     static const D3DVERTEXELEMENT9 decl_elements[] = {
7951         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7952         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7953         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7954         D3DDECL_END()
7955     };
7956
7957     /* use asymmetric matrix to test loading */
7958     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7959     float scale, offset;
7960
7961     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7962     IDirect3DTexture9           *texture            = NULL;
7963
7964     memset(&caps, 0, sizeof(caps));
7965     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7966     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7967     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7968         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7969         return;
7970     } else {
7971         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7972          * They report that it is not supported, but after that bump mapping works properly. So just test
7973          * if the format is generally supported, and check the BUMPENVMAP flag
7974          */
7975         IDirect3D9 *d3d9;
7976
7977         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7978         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7979                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7980         L6V5U5_supported = SUCCEEDED(hr);
7981         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7982                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7983         IDirect3D9_Release(d3d9);
7984         if(FAILED(hr)) {
7985             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7986             return;
7987         }
7988     }
7989
7990     /* Generate the textures */
7991     generate_bumpmap_textures(device);
7992
7993     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7994     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7996     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7997     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7998     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7999     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
8000     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8001
8002     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
8003     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8004     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
8005     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8006     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
8007     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8008
8009     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8010     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8011     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8012     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8013     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8014     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8015
8016     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8017     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8018
8019     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8020     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
8021
8022     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
8023     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
8024
8025
8026     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
8027     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
8028     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
8029     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
8030
8031     hr = IDirect3DDevice9_BeginScene(device);
8032     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8033
8034     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8035     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8036
8037     hr = IDirect3DDevice9_EndScene(device);
8038     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8039
8040     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
8041      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
8042      * But since testing the color match is not the purpose of the test don't be too picky
8043      */
8044     color = getPixelColor(device, 320-32, 240);
8045     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8046     color = getPixelColor(device, 320+32, 240);
8047     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8048     color = getPixelColor(device, 320, 240-32);
8049     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8050     color = getPixelColor(device, 320, 240+32);
8051     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
8052     color = getPixelColor(device, 320, 240);
8053     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8054     color = getPixelColor(device, 320+32, 240+32);
8055     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8056     color = getPixelColor(device, 320-32, 240+32);
8057     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8058     color = getPixelColor(device, 320+32, 240-32);
8059     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8060     color = getPixelColor(device, 320-32, 240-32);
8061     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
8062     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8063     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8064
8065     for(i = 0; i < 2; i++) {
8066         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
8067         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
8068         IDirect3DTexture9_Release(texture); /* For the GetTexture */
8069         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
8070         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
8071         IDirect3DTexture9_Release(texture); /* To destroy it */
8072     }
8073
8074     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
8075         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
8076         goto cleanup;
8077     }
8078     if(L6V5U5_supported == FALSE) {
8079         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
8080         goto cleanup;
8081     }
8082
8083     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
8084     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8085     /* This test only tests the luminance part. The bumpmapping part was already tested above and
8086      * would only make this test more complicated
8087      */
8088     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
8089     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8090     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8091     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8092
8093     memset(&locked_rect, 0, sizeof(locked_rect));
8094     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
8095     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8096     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
8097     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8098     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8099
8100     memset(&locked_rect, 0, sizeof(locked_rect));
8101     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
8102     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
8103     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
8104     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8105     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
8106
8107     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8108     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8109     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8110     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8111
8112     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
8113     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8114     scale = 2.0;
8115     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8116     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8117     offset = 0.1;
8118     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8119     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8120
8121     hr = IDirect3DDevice9_BeginScene(device);
8122     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8123     if(SUCCEEDED(hr)) {
8124         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8125         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8126         hr = IDirect3DDevice9_EndScene(device);
8127         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8128     }
8129
8130     color = getPixelColor(device, 320, 240);
8131     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
8132      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
8133      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
8134      */
8135     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
8136     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8137     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8138
8139     /* Check a result scale factor > 1.0 */
8140     scale = 10;
8141     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8142     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8143     offset = 10;
8144     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8145     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8146
8147     hr = IDirect3DDevice9_BeginScene(device);
8148     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8149     if(SUCCEEDED(hr)) {
8150         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8151         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8152         hr = IDirect3DDevice9_EndScene(device);
8153         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8154     }
8155     color = getPixelColor(device, 320, 240);
8156     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8157     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8158     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8159
8160     /* Check clamping in the scale factor calculation */
8161     scale = 1000;
8162     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
8163     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8164     offset = -1;
8165     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
8166     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8167
8168     hr = IDirect3DDevice9_BeginScene(device);
8169     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
8170     if(SUCCEEDED(hr)) {
8171         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
8172         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
8173         hr = IDirect3DDevice9_EndScene(device);
8174         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
8175     }
8176     color = getPixelColor(device, 320, 240);
8177     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
8178     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8179     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
8180
8181     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8182     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8183     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8184     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8185
8186     IDirect3DTexture9_Release(tex1);
8187     IDirect3DTexture9_Release(tex2);
8188
8189 cleanup:
8190     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8191     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8192     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8193     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8194
8195     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8196     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8197     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8198 }
8199
8200 static void stencil_cull_test(IDirect3DDevice9 *device) {
8201     HRESULT hr;
8202     IDirect3DSurface9 *depthstencil = NULL;
8203     D3DSURFACE_DESC desc;
8204     float quad1[] = {
8205         -1.0,   -1.0,   0.1,
8206          0.0,   -1.0,   0.1,
8207         -1.0,    0.0,   0.1,
8208          0.0,    0.0,   0.1,
8209     };
8210     float quad2[] = {
8211          0.0,   -1.0,   0.1,
8212          1.0,   -1.0,   0.1,
8213          0.0,    0.0,   0.1,
8214          1.0,    0.0,   0.1,
8215     };
8216     float quad3[] = {
8217         0.0,    0.0,   0.1,
8218         1.0,    0.0,   0.1,
8219         0.0,    1.0,   0.1,
8220         1.0,    1.0,   0.1,
8221     };
8222     float quad4[] = {
8223         -1.0,    0.0,   0.1,
8224          0.0,    0.0,   0.1,
8225         -1.0,    1.0,   0.1,
8226          0.0,    1.0,   0.1,
8227     };
8228     struct vertex painter[] = {
8229        {-1.0,   -1.0,   0.0,    0x00000000},
8230        { 1.0,   -1.0,   0.0,    0x00000000},
8231        {-1.0,    1.0,   0.0,    0x00000000},
8232        { 1.0,    1.0,   0.0,    0x00000000},
8233     };
8234     WORD indices_cw[]  = {0, 1, 3};
8235     WORD indices_ccw[] = {0, 2, 3};
8236     unsigned int i;
8237     DWORD color;
8238
8239     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8240     if(depthstencil == NULL) {
8241         skip("No depth stencil buffer\n");
8242         return;
8243     }
8244     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8245     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8246     IDirect3DSurface9_Release(depthstencil);
8247     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8248         skip("No 4 or 8 bit stencil surface\n");
8249         return;
8250     }
8251
8252     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8253     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8254     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8255
8256     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8257     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8258     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8259     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8260     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8261     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8262     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8264
8265     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8266     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8267     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8268     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8269     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8270     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8271
8272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8274     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8275     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8276
8277     /* First pass: Fill the stencil buffer with some values... */
8278     hr = IDirect3DDevice9_BeginScene(device);
8279     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8280     if(SUCCEEDED(hr))
8281     {
8282         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8283         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8284         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8285                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8286         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8287         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8288                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8289         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8290
8291         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8292         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8293         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8294         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8295         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8296                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8297         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8298         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8299                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8300         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8301
8302         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8303         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8304         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8305                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8306         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8307         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8308                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8309         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8310
8311         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8312         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8313         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8314                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8315         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8316         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8317                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8318         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8319
8320         hr = IDirect3DDevice9_EndScene(device);
8321         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8322     }
8323
8324     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8325     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8326     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8327     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8328     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8329     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8330     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8331     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8332     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8333     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8334     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8335     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8336     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8337
8338     /* 2nd pass: Make the stencil values visible */
8339     hr = IDirect3DDevice9_BeginScene(device);
8340     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8341     if(SUCCEEDED(hr))
8342     {
8343         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8344         for(i = 0; i < 16; i++) {
8345             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8346             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8347
8348             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8349             painter[1].diffuse = (i * 16);
8350             painter[2].diffuse = (i * 16);
8351             painter[3].diffuse = (i * 16);
8352             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8353             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8354         }
8355         hr = IDirect3DDevice9_EndScene(device);
8356         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8357     }
8358
8359     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8360     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8361
8362     color = getPixelColor(device, 160, 420);
8363     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8364     color = getPixelColor(device, 160, 300);
8365     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8366
8367     color = getPixelColor(device, 480, 420);
8368     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8369     color = getPixelColor(device, 480, 300);
8370     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8371
8372     color = getPixelColor(device, 160, 180);
8373     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8374     color = getPixelColor(device, 160, 60);
8375     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8376
8377     color = getPixelColor(device, 480, 180);
8378     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8379     color = getPixelColor(device, 480, 60);
8380     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8381
8382     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8383     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8384 }
8385
8386 static void vpos_register_test(IDirect3DDevice9 *device)
8387 {
8388     HRESULT hr;
8389     DWORD color;
8390     const DWORD shader_code[] = {
8391     0xffff0300,                                                             /* ps_3_0                     */
8392     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8393     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8394     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8395     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8396     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8397     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8398     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8399     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8400     0x0000ffff                                                              /* end                        */
8401     };
8402     const DWORD shader_frac_code[] = {
8403     0xffff0300,                                                             /* ps_3_0                     */
8404     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8405     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8406     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8407     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8408     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8409     0x0000ffff                                                              /* end                        */
8410     };
8411     IDirect3DPixelShader9 *shader, *shader_frac;
8412     IDirect3DSurface9 *surface = NULL, *backbuffer;
8413     const float quad[] = {
8414         -1.0,   -1.0,   0.1,    0.0,    0.0,
8415          1.0,   -1.0,   0.1,    1.0,    0.0,
8416         -1.0,    1.0,   0.1,    0.0,    1.0,
8417          1.0,    1.0,   0.1,    1.0,    1.0,
8418     };
8419     D3DLOCKED_RECT lr;
8420     float constant[4] = {1.0, 0.0, 320, 240};
8421     DWORD *pos;
8422
8423     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8424     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8425     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8426     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8427     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8428     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8429     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8430     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8431     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8432     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8433     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8434     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8435
8436     hr = IDirect3DDevice9_BeginScene(device);
8437     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8438     if(SUCCEEDED(hr)) {
8439         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8440         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8441         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8442         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8443         hr = IDirect3DDevice9_EndScene(device);
8444         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8445     }
8446
8447     /* This has to be pixel exact */
8448     color = getPixelColor(device, 319, 239);
8449     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8450     color = getPixelColor(device, 320, 239);
8451     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8452     color = getPixelColor(device, 319, 240);
8453     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8454     color = getPixelColor(device, 320, 240);
8455     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8456     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8457
8458     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8459                                              &surface, NULL);
8460     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8461     hr = IDirect3DDevice9_BeginScene(device);
8462     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8463     if(SUCCEEDED(hr)) {
8464         constant[2] = 16; constant[3] = 16;
8465         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8466         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8467         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8468         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8469         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8470         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8471         hr = IDirect3DDevice9_EndScene(device);
8472         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8473     }
8474     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8475     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8476
8477     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8478     color = *pos & 0x00ffffff;
8479     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8480     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8481     color = *pos & 0x00ffffff;
8482     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8483     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8484     color = *pos & 0x00ffffff;
8485     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8486     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8487     color = *pos & 0x00ffffff;
8488     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8489
8490     hr = IDirect3DSurface9_UnlockRect(surface);
8491     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8492
8493     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8494      * have full control over the multisampling setting inside this test
8495      */
8496     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8497     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8498     hr = IDirect3DDevice9_BeginScene(device);
8499     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8500     if(SUCCEEDED(hr)) {
8501         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8502         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8503         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8504         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8505         hr = IDirect3DDevice9_EndScene(device);
8506         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8507     }
8508     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8509     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8510
8511     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8512     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8513
8514     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8515     color = *pos & 0x00ffffff;
8516     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8517
8518     hr = IDirect3DSurface9_UnlockRect(surface);
8519     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8520
8521     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8522     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8523     IDirect3DPixelShader9_Release(shader);
8524     IDirect3DPixelShader9_Release(shader_frac);
8525     if(surface) IDirect3DSurface9_Release(surface);
8526     IDirect3DSurface9_Release(backbuffer);
8527 }
8528
8529 static void pointsize_test(IDirect3DDevice9 *device)
8530 {
8531     HRESULT hr;
8532     D3DCAPS9 caps;
8533     D3DMATRIX matrix;
8534     D3DMATRIX identity;
8535     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8536     DWORD color;
8537     IDirect3DTexture9 *tex1, *tex2;
8538     D3DLOCKED_RECT lr;
8539     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8540                                 0x00000000, 0x00000000};
8541     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8542                                 0x00000000, 0x0000ff00};
8543
8544     const float vertices[] = {
8545         64,     64,     0.1,
8546         128,    64,     0.1,
8547         192,    64,     0.1,
8548         256,    64,     0.1,
8549         320,    64,     0.1,
8550         384,    64,     0.1,
8551         448,    64,     0.1,
8552         512,    64,     0.1,
8553         576,    64,     0.1,
8554     };
8555
8556     /* 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 */
8557     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;
8558     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;
8559     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;
8560     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;
8561
8562     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;
8563     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;
8564     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;
8565     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;
8566
8567     memset(&caps, 0, sizeof(caps));
8568     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8569     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8570     if(caps.MaxPointSize < 32.0) {
8571         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8572         return;
8573     }
8574
8575     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8576     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8577     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8578     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8579     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8580     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8581     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8582     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8583
8584     hr = IDirect3DDevice9_BeginScene(device);
8585     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8586     if(SUCCEEDED(hr)) {
8587         ptsize = 16.0;
8588         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8589         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8590         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8591         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8592
8593         ptsize = 32.0;
8594         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8595         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8596         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8597         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8598
8599         ptsize = 31.5;
8600         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8601         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8602         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8603         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8604
8605         if(caps.MaxPointSize >= 64.0) {
8606             ptsize = 64.0;
8607             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8608             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8609             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8610             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8611
8612             ptsize = 63.75;
8613             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8614             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8615             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8616             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8617         }
8618
8619         ptsize = 1.0;
8620         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8621         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8622         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8623         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8624
8625         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8626         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8627         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8628         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8629
8630         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8631         ptsize = 16.0;
8632         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8633         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8634         ptsize = 1.0;
8635         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8636         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8637         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8638         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8639
8640         /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8641          * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8642          */
8643         ptsize = 4.0;
8644         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8645         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8646         ptsize = 16.0;
8647         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8648         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8649         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8650         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8651
8652         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8653         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8654
8655         /* pointsize < pointsize_min < pointsize_max?
8656          * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8657          */
8658         ptsize = 1.0;
8659         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8660         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8661         ptsize = 16.0;
8662         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8663         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8664         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8665         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8666
8667         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8668         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8669
8670         hr = IDirect3DDevice9_EndScene(device);
8671         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8672     }
8673     color = getPixelColor(device, 64-9, 64-9);
8674     ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8675     color = getPixelColor(device, 64-8, 64-8);
8676     ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8677     color = getPixelColor(device, 64-7, 64-7);
8678     ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8679     color = getPixelColor(device, 64+7, 64+7);
8680     ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8681     color = getPixelColor(device, 64+8, 64+8);
8682     ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8683     color = getPixelColor(device, 64+9, 64+9);
8684     ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8685
8686     color = getPixelColor(device, 128-17, 64-17);
8687     ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8688     color = getPixelColor(device, 128-16, 64-16);
8689     ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8690     color = getPixelColor(device, 128-15, 64-15);
8691     ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8692     color = getPixelColor(device, 128+15, 64+15);
8693     ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8694     color = getPixelColor(device, 128+16, 64+16);
8695     ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8696     color = getPixelColor(device, 128+17, 64+17);
8697     ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8698
8699     color = getPixelColor(device, 192-17, 64-17);
8700     ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8701     color = getPixelColor(device, 192-16, 64-16);
8702     todo_wine ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8703     color = getPixelColor(device, 192-15, 64-15);
8704     ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8705     color = getPixelColor(device, 192+15, 64+15);
8706     ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8707     color = getPixelColor(device, 192+16, 64+16);
8708     ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8709     color = getPixelColor(device, 192+17, 64+17);
8710     ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8711
8712     if(caps.MaxPointSize >= 64.0) {
8713         color = getPixelColor(device, 256-33, 64-33);
8714         ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8715         color = getPixelColor(device, 256-32, 64-32);
8716         todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8717         color = getPixelColor(device, 256-31, 64-31);
8718         ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8719         color = getPixelColor(device, 256+31, 64+31);
8720         ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8721         color = getPixelColor(device, 256+32, 64+32);
8722         ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8723         color = getPixelColor(device, 256+33, 64+33);
8724         ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8725
8726         color = getPixelColor(device, 384-33, 64-33);
8727         ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8728         color = getPixelColor(device, 384-32, 64-32);
8729         ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8730         color = getPixelColor(device, 384-31, 64-31);
8731         ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8732         color = getPixelColor(device, 384+31, 64+31);
8733         ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8734         color = getPixelColor(device, 384+32, 64+32);
8735         ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8736         color = getPixelColor(device, 384+33, 64+33);
8737         ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8738     }
8739
8740     color = getPixelColor(device, 320-1, 64-1);
8741     ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8742     color = getPixelColor(device, 320-0, 64-0);
8743     ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8744     color = getPixelColor(device, 320+1, 64+1);
8745     ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8746
8747     /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8748     color = getPixelColor(device, 448-4, 64-4);
8749     ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8750     color = getPixelColor(device, 448+4, 64+4);
8751     ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8752
8753     /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8754     color = getPixelColor(device, 512-4, 64-4);
8755     ok(color == 0x000000ff, "pSize: Pixel (512-4),(64-4) has color 0x%08x, expected 0x000000ff\n", color);
8756     color = getPixelColor(device, 512+4, 64+4);
8757     ok(color == 0x000000ff, "pSize: Pixel (512+4),(64+4) has color 0x%08x, expected 0x000000ff\n", color);
8758
8759     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8760      * Don't be overly picky - just show that the point is bigger than 1 pixel
8761      */
8762     color = getPixelColor(device, 576-4, 64-4);
8763     ok(color == 0x00ffffff, "pSize: Pixel (576-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8764     color = getPixelColor(device, 576+4, 64+4);
8765     ok(color == 0x00ffffff, "pSize: Pixel (576+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8766
8767     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8768
8769     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8770      * generates texture coordinates for the point(result: Yes, it does)
8771      *
8772      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8773      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8774      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8775      */
8776     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8777     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8778
8779     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8780     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8781     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8782     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8783     memset(&lr, 0, sizeof(lr));
8784     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8785     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8786     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8787     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8788     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8789     memset(&lr, 0, sizeof(lr));
8790     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8791     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8792     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8793     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8794     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8795     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8796     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8797     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8798     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8799     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8800     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8801     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8802     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8803     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8804     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8805     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8806     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8807     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8808     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8809
8810     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8811     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8812     ptsize = 32.0;
8813     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8814     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8815
8816     hr = IDirect3DDevice9_BeginScene(device);
8817     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8818     if(SUCCEEDED(hr))
8819     {
8820         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8821         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8822         hr = IDirect3DDevice9_EndScene(device);
8823         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8824     }
8825
8826     color = getPixelColor(device, 64-4, 64-4);
8827     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8828     color = getPixelColor(device, 64-4, 64+4);
8829     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8830     color = getPixelColor(device, 64+4, 64+4);
8831     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8832     color = getPixelColor(device, 64+4, 64-4);
8833     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8834     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8835
8836     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8837     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8838     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8839     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8840     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8841     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8842     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8843     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8844     IDirect3DTexture9_Release(tex1);
8845     IDirect3DTexture9_Release(tex2);
8846
8847     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8848     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8849     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8850     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8851     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8852     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8853 }
8854
8855 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8856 {
8857     HRESULT hr;
8858     IDirect3DPixelShader9 *ps;
8859     IDirect3DTexture9 *tex1, *tex2;
8860     IDirect3DSurface9 *surf1, *surf2, *backbuf;
8861     D3DCAPS9 caps;
8862     DWORD color;
8863     DWORD shader_code[] = {
8864     0xffff0300,                                                             /* ps_3_0             */
8865     0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8866     0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8867     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0        */
8868     0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1        */
8869     0x0000ffff                                                              /* END                */
8870     };
8871     float quad[] = {
8872        -1.0,   -1.0,    0.1,
8873         1.0,   -1.0,    0.1,
8874        -1.0,    1.0,    0.1,
8875         1.0,    1.0,    0.1,
8876     };
8877     float texquad[] = {
8878        -1.0,   -1.0,    0.1,    0.0,    0.0,
8879         0.0,   -1.0,    0.1,    1.0,    0.0,
8880        -1.0,    1.0,    0.1,    0.0,    1.0,
8881         0.0,    1.0,    0.1,    1.0,    1.0,
8882
8883         0.0,   -1.0,    0.1,    0.0,    0.0,
8884         1.0,   -1.0,    0.1,    1.0,    0.0,
8885         0.0,    1.0,    0.1,    0.0,    1.0,
8886         1.0,    1.0,    0.1,    1.0,    1.0,
8887     };
8888
8889     memset(&caps, 0, sizeof(caps));
8890     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8891     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8892     if(caps.NumSimultaneousRTs < 2) {
8893         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8894         return;
8895     }
8896
8897     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8898     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8899
8900     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8901     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8902     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8903     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8904     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8905     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8906
8907     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8908     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8909     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8910     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8911     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8912     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8913
8914     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8915     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8916     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8917     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8918     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8919     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8920     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8921     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8922
8923     hr = IDirect3DDevice9_BeginScene(device);
8924     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8925     if(SUCCEEDED(hr)) {
8926         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8927         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8928
8929         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8930         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8931         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8932         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8933         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8934         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8935         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8936         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8937
8938         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8939         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8940         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8941         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8942
8943         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8945         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8946         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8947
8948         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8949         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8950
8951         hr = IDirect3DDevice9_EndScene(device);
8952         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8953     }
8954
8955     color = getPixelColor(device, 160, 240);
8956     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8957     color = getPixelColor(device, 480, 240);
8958     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8959     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8960
8961     IDirect3DPixelShader9_Release(ps);
8962     IDirect3DTexture9_Release(tex1);
8963     IDirect3DTexture9_Release(tex2);
8964     IDirect3DSurface9_Release(surf1);
8965     IDirect3DSurface9_Release(surf2);
8966     IDirect3DSurface9_Release(backbuf);
8967 }
8968
8969 struct formats {
8970     const char *fmtName;
8971     D3DFORMAT textureFormat;
8972     DWORD resultColorBlending;
8973     DWORD resultColorNoBlending;
8974 };
8975
8976 const struct formats test_formats[] = {
8977   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8978   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8979   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8980   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8981   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8982   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8983   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8984   { NULL, 0 }
8985 };
8986
8987 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8988 {
8989     HRESULT hr;
8990     IDirect3DTexture9 *offscreenTexture = NULL;
8991     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8992     IDirect3D9 *d3d = NULL;
8993     DWORD color;
8994     DWORD r0, g0, b0, r1, g1, b1;
8995     int fmt_index;
8996
8997     static const float quad[][5] = {
8998         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8999         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
9000         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
9001         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
9002     };
9003
9004     /* Quad with R=0x10, G=0x20 */
9005     static const struct vertex quad1[] = {
9006         {-1.0f, -1.0f, 0.1f, 0x80102000},
9007         {-1.0f,  1.0f, 0.1f, 0x80102000},
9008         { 1.0f, -1.0f, 0.1f, 0x80102000},
9009         { 1.0f,  1.0f, 0.1f, 0x80102000},
9010     };
9011
9012     /* Quad with R=0x20, G=0x10 */
9013     static const struct vertex quad2[] = {
9014         {-1.0f, -1.0f, 0.1f, 0x80201000},
9015         {-1.0f,  1.0f, 0.1f, 0x80201000},
9016         { 1.0f, -1.0f, 0.1f, 0x80201000},
9017         { 1.0f,  1.0f, 0.1f, 0x80201000},
9018     };
9019
9020     IDirect3DDevice9_GetDirect3D(device, &d3d);
9021
9022     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9023     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
9024     if(!backbuffer) {
9025         goto out;
9026     }
9027
9028     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
9029     {
9030         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
9031         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
9032            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
9033            continue;
9034         }
9035
9036         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9037         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9038
9039         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9040         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
9041         if(!offscreenTexture) {
9042             continue;
9043         }
9044
9045         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9046         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
9047         if(!offscreen) {
9048             continue;
9049         }
9050
9051         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9052         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9053
9054         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9055         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9057         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9058         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9059         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
9060         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9061         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
9062         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9063         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9064
9065         /* Below we will draw two quads with different colors and try to blend them together.
9066          * The result color is compared with the expected outcome.
9067          */
9068         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
9069             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9070             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9071             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
9072             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
9073
9074             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9075             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9076
9077             /* Draw a quad using color 0x0010200 */
9078             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
9079             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9080             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
9081             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9082             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9083             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9084
9085             /* Draw a quad using color 0x0020100 */
9086             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9087             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9088             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9089             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9090             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9091             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
9092
9093             /* We don't want to blend the result on the backbuffer */
9094             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9095             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9096
9097             /* Prepare rendering the 'blended' texture quad to the backbuffer */
9098             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9099             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
9100             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9101             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
9102
9103             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9104             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
9105
9106             /* This time with the texture */
9107             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9108             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
9109
9110             IDirect3DDevice9_EndScene(device);
9111         }
9112
9113         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
9114             /* Compare the color of the center quad with our expectation */
9115             color = getPixelColor(device, 320, 240);
9116             r0 = (color & 0x00ff0000) >> 16;
9117             g0 = (color & 0x0000ff00) >>  8;
9118             b0 = (color & 0x000000ff) >>  0;
9119
9120             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
9121             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
9122             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
9123
9124             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
9125                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
9126                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
9127                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
9128         } else {
9129             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
9130              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
9131              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
9132             color = getPixelColor(device, 320, 240);
9133             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);
9134         }
9135         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9136
9137         IDirect3DDevice9_SetTexture(device, 0, NULL);
9138         if(offscreenTexture) {
9139             IDirect3DTexture9_Release(offscreenTexture);
9140         }
9141         if(offscreen) {
9142             IDirect3DSurface9_Release(offscreen);
9143         }
9144     }
9145
9146 out:
9147     /* restore things */
9148     if(backbuffer) {
9149         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9150         IDirect3DSurface9_Release(backbuffer);
9151     }
9152 }
9153
9154 static void tssargtemp_test(IDirect3DDevice9 *device)
9155 {
9156     HRESULT hr;
9157     DWORD color;
9158     static const struct vertex quad[] = {
9159         {-1.0,     -1.0,    0.1,    0x00ff0000},
9160         { 1.0,     -1.0,    0.1,    0x00ff0000},
9161         {-1.0,      1.0,    0.1,    0x00ff0000},
9162         { 1.0,      1.0,    0.1,    0x00ff0000}
9163     };
9164     D3DCAPS9 caps;
9165
9166     memset(&caps, 0, sizeof(caps));
9167     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9168     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9169     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9170         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9171         return;
9172     }
9173
9174     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9175     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9176
9177     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9178     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9179     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9180     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9181
9182     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9183     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9184     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9185     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9186     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9187     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9188
9189     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9190     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9191     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9192     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9193     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9194     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9195
9196     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9197     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9198
9199     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9200     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9201     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9202     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9203
9204     hr = IDirect3DDevice9_BeginScene(device);
9205     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9206     if(SUCCEEDED(hr)) {
9207         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9208         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9209         hr = IDirect3DDevice9_EndScene(device);
9210         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9211     }
9212     color = getPixelColor(device, 320, 240);
9213     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9214     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9215
9216     /* Set stage 1 back to default */
9217     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9218     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9219     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9220     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9221     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9222     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9223     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9224     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9225     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9226     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9227 }
9228
9229 struct testdata
9230 {
9231     DWORD idxVertex; /* number of instances in the first stream */
9232     DWORD idxColor; /* number of instances in the second stream */
9233     DWORD idxInstance; /* should be 1 ?? */
9234     DWORD color1; /* color 1 instance */
9235     DWORD color2; /* color 2 instance */
9236     DWORD color3; /* color 3 instance */
9237     DWORD color4; /* color 4 instance */
9238     WORD strVertex; /* specify which stream to use 0-2*/
9239     WORD strColor;
9240     WORD strInstance;
9241 };
9242
9243 static const struct testdata testcases[]=
9244 {
9245     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9246     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9247     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9248     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9249     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9250     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9251     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9252     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9253     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9254     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9255     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9256     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9257     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9258     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9259     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9260 /*
9261     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9262     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9263 */
9264 };
9265
9266 /* Drawing Indexed Geometry with instances*/
9267 static void stream_test(IDirect3DDevice9 *device)
9268 {
9269     IDirect3DVertexBuffer9 *vb = NULL;
9270     IDirect3DVertexBuffer9 *vb2 = NULL;
9271     IDirect3DVertexBuffer9 *vb3 = NULL;
9272     IDirect3DIndexBuffer9 *ib = NULL;
9273     IDirect3DVertexDeclaration9 *pDecl = NULL;
9274     IDirect3DVertexShader9 *shader = NULL;
9275     HRESULT hr;
9276     BYTE *data;
9277     DWORD color;
9278     DWORD ind;
9279     unsigned i;
9280
9281     const DWORD shader_code[] =
9282     {
9283         0xfffe0101,                                     /* vs_1_1 */
9284         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9285         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9286         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9287         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9288         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9289         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9290         0x0000ffff
9291     };
9292
9293     const float quad[][3] =
9294     {
9295         {-0.5f, -0.5f,  1.1f}, /*0 */
9296         {-0.5f,  0.5f,  1.1f}, /*1 */
9297         { 0.5f, -0.5f,  1.1f}, /*2 */
9298         { 0.5f,  0.5f,  1.1f}, /*3 */
9299     };
9300
9301     const float vertcolor[][4] =
9302     {
9303         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9304         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9305         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9306         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9307     };
9308
9309     /* 4 position for 4 instances */
9310     const float instancepos[][3] =
9311     {
9312         {-0.6f,-0.6f, 0.0f},
9313         { 0.6f,-0.6f, 0.0f},
9314         { 0.6f, 0.6f, 0.0f},
9315         {-0.6f, 0.6f, 0.0f},
9316     };
9317
9318     short indices[] = {0, 1, 2, 1, 2, 3};
9319
9320     D3DVERTEXELEMENT9 decl[] =
9321     {
9322         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9323         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9324         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9325         D3DDECL_END()
9326     };
9327
9328     /* set the default value because it isn't done in wine? */
9329     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9330     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9331
9332     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9333     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9334     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9335
9336     /* check wrong cases */
9337     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9338     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9339     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9340     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9341     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9342     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9343     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9344     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9345     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9346     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9347     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9348     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9349     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9350     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9351     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9352     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9353     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9354     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9355     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9356     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9357
9358     /* set the default value back */
9359     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9360     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9361
9362     /* create all VertexBuffers*/
9363     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9364     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9365     if(!vb) {
9366         skip("Failed to create a vertex buffer\n");
9367         return;
9368     }
9369     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9370     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9371     if(!vb2) {
9372         skip("Failed to create a vertex buffer\n");
9373         goto out;
9374     }
9375     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9376     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9377     if(!vb3) {
9378         skip("Failed to create a vertex buffer\n");
9379         goto out;
9380     }
9381
9382     /* create IndexBuffer*/
9383     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9384     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9385     if(!ib) {
9386         skip("Failed to create a index buffer\n");
9387         goto out;
9388     }
9389
9390     /* copy all Buffers (Vertex + Index)*/
9391     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9392     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9393     memcpy(data, quad, sizeof(quad));
9394     hr = IDirect3DVertexBuffer9_Unlock(vb);
9395     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9396     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9397     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9398     memcpy(data, vertcolor, sizeof(vertcolor));
9399     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9400     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9401     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9402     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9403     memcpy(data, instancepos, sizeof(instancepos));
9404     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9405     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9406     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9407     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9408     memcpy(data, indices, sizeof(indices));
9409     hr = IDirect3DIndexBuffer9_Unlock(ib);
9410     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9411
9412     /* create VertexShader */
9413     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9414     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9415     if(!shader) {
9416         skip("Failed to create a vetex shader\n");
9417         goto out;
9418     }
9419
9420     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9421     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9422
9423     hr = IDirect3DDevice9_SetIndices(device, ib);
9424     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9425
9426     /* run all tests */
9427     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9428     {
9429         struct testdata act = testcases[i];
9430         decl[0].Stream = act.strVertex;
9431         decl[1].Stream = act.strColor;
9432         decl[2].Stream = act.strInstance;
9433         /* create VertexDeclarations */
9434         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9435         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9436
9437         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9438         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9439
9440         hr = IDirect3DDevice9_BeginScene(device);
9441         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9442         if(SUCCEEDED(hr))
9443         {
9444             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9445             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9446
9447             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9448             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9449             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9450             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9451
9452             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9453             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9454             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9455             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9456
9457             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9458             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9459             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9460             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9461
9462             /* don't know if this is right (1*3 and 4*1)*/
9463             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9464             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9465             hr = IDirect3DDevice9_EndScene(device);
9466             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9467
9468             /* set all StreamSource && StreamSourceFreq back to default */
9469             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9470             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9471             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9472             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9473             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9474             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9475             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9476             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9477             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9478             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9479             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9480             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9481         }
9482
9483         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9484         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9485
9486         color = getPixelColor(device, 160, 360);
9487         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9488         color = getPixelColor(device, 480, 360);
9489         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9490         color = getPixelColor(device, 480, 120);
9491         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9492         color = getPixelColor(device, 160, 120);
9493         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9494
9495         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9496         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9497     }
9498
9499     hr = IDirect3DDevice9_SetIndices(device, NULL);
9500     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9501
9502 out:
9503     if(vb) IDirect3DVertexBuffer9_Release(vb);
9504     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9505     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9506     if(ib)IDirect3DIndexBuffer9_Release(ib);
9507     if(shader)IDirect3DVertexShader9_Release(shader);
9508 }
9509
9510 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9511     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9512     IDirect3DTexture9 *dsttex = NULL;
9513     HRESULT hr;
9514     DWORD color;
9515     D3DRECT r1 = {0,  0,  50,  50 };
9516     D3DRECT r2 = {50, 0,  100, 50 };
9517     D3DRECT r3 = {50, 50, 100, 100};
9518     D3DRECT r4 = {0,  50,  50, 100};
9519     const float quad[] = {
9520         -1.0,   -1.0,   0.1,    0.0,    0.0,
9521          1.0,   -1.0,   0.1,    1.0,    0.0,
9522         -1.0,    1.0,   0.1,    0.0,    1.0,
9523          1.0,    1.0,   0.1,    1.0,    1.0,
9524     };
9525
9526     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9527     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9528
9529     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9530     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9531     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9532     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9533
9534     if(!src || !dsttex) {
9535         skip("One or more test resources could not be created\n");
9536         goto cleanup;
9537     }
9538
9539     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9540     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9541
9542     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9543     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9544
9545     /* Clear the StretchRect destination for debugging */
9546     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9547     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9548     hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9549     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9550
9551     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9552     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9553
9554     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9555     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9556     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9558     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9559     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9560     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9561     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9562
9563     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9564      * the target -> texture GL blit path
9565      */
9566     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9567     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9568     IDirect3DSurface9_Release(dst);
9569
9570     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9571     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9572
9573     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9574     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9575     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9576     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9577     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9578     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9579     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9580     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9581
9582     hr = IDirect3DDevice9_BeginScene(device);
9583     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9584     if(SUCCEEDED(hr)) {
9585         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9586         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9587         hr = IDirect3DDevice9_EndScene(device);
9588         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9589     }
9590
9591     color = getPixelColor(device, 160, 360);
9592     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9593     color = getPixelColor(device, 480, 360);
9594     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9595     color = getPixelColor(device, 480, 120);
9596     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9597     color = getPixelColor(device, 160, 120);
9598     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9599     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9600     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9601
9602     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9603     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9604     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9605     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9606
9607 cleanup:
9608     if(src) IDirect3DSurface9_Release(src);
9609     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9610     if(dsttex) IDirect3DTexture9_Release(dsttex);
9611 }
9612
9613 static void texop_test(IDirect3DDevice9 *device)
9614 {
9615     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9616     IDirect3DTexture9 *texture = NULL;
9617     D3DLOCKED_RECT locked_rect;
9618     D3DCOLOR color;
9619     D3DCAPS9 caps;
9620     HRESULT hr;
9621     unsigned i;
9622
9623     static const struct {
9624         float x, y, z;
9625         float s, t;
9626         D3DCOLOR diffuse;
9627     } quad[] = {
9628         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9629         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9630         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9631         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9632     };
9633
9634     static const D3DVERTEXELEMENT9 decl_elements[] = {
9635         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9636         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9637         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9638         D3DDECL_END()
9639     };
9640
9641     static const struct {
9642         D3DTEXTUREOP op;
9643         const char *name;
9644         DWORD caps_flag;
9645         D3DCOLOR result;
9646     } test_data[] = {
9647         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9648         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9649         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9650         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9651         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9652         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9653         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9654         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9655         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9656         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9657         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9658         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9659         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9660         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9661         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9662         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9663         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9664         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9665         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9666         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9667         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9668         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9669         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9670     };
9671
9672     memset(&caps, 0, sizeof(caps));
9673     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9674     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9675
9676     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9677     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9678     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9679     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9680
9681     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9682     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9683     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9684     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9685     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9686     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9687     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9688     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9689     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9690
9691     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9692     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9693     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9694     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9695     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9696     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9697
9698     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9699     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9700
9701     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9702     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9703     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9704     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9705     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9706     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9707
9708     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9709     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9710
9711     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9712     {
9713         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9714         {
9715             skip("tex operation %s not supported\n", test_data[i].name);
9716             continue;
9717         }
9718
9719         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9720         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9721
9722         hr = IDirect3DDevice9_BeginScene(device);
9723         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9724
9725         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9726         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9727
9728         hr = IDirect3DDevice9_EndScene(device);
9729         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9730
9731         color = getPixelColor(device, 320, 240);
9732         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9733                 test_data[i].name, color, test_data[i].result);
9734
9735         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9736         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9737     }
9738
9739     if (texture) IDirect3DTexture9_Release(texture);
9740     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9741 }
9742
9743 static void yuv_color_test(IDirect3DDevice9 *device) {
9744     HRESULT hr;
9745     IDirect3DSurface9 *surface = NULL, *target = NULL;
9746     unsigned int fmt, i;
9747     D3DFORMAT format;
9748     const char *fmt_string;
9749     D3DLOCKED_RECT lr;
9750     IDirect3D9 *d3d;
9751     HRESULT color;
9752     DWORD ref_color_left, ref_color_right;
9753
9754     struct {
9755         DWORD in;           /* The input color */
9756         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9757         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9758         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9759         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9760     } test_data[] = {
9761     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9762      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9763      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9764      * that
9765      */
9766       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9767       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9768       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9769       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9770       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9771       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9772       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9773       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9774       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9775       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9776       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9777       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9778       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9779       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9780
9781       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9782       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9783       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9784       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9785     };
9786
9787     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9788     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9789     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9790     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9791
9792     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9793     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9794
9795     for(fmt = 0; fmt < 2; fmt++) {
9796         if(fmt == 0) {
9797             format = D3DFMT_UYVY;
9798             fmt_string = "D3DFMT_UYVY";
9799         } else {
9800             format = D3DFMT_YUY2;
9801             fmt_string = "D3DFMT_YUY2";
9802         }
9803
9804         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9805                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9806                        */
9807         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9808                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9809             skip("%s is not supported\n", fmt_string);
9810             continue;
9811         }
9812
9813         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9814         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9815         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9816
9817         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9818             if(fmt == 0) {
9819                 ref_color_left = test_data[i].uyvy_left;
9820                 ref_color_right = test_data[i].uyvy_right;
9821             } else {
9822                 ref_color_left = test_data[i].yuy2_left;
9823                 ref_color_right = test_data[i].yuy2_right;
9824             }
9825
9826             memset(&lr, 0, sizeof(lr));
9827             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9828             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9829             *((DWORD *) lr.pBits) = test_data[i].in;
9830             hr = IDirect3DSurface9_UnlockRect(surface);
9831             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9832
9833             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9834             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9835             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9836             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9837
9838             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9839              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9840              * want to add tests for the filtered pixels as well.
9841              *
9842              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9843              * differently, so we need a max diff of 16
9844              */
9845             color = getPixelColor(device, 40, 240);
9846             ok(color_match(color, ref_color_left, 18),
9847                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9848                test_data[i].in, color, ref_color_left, fmt_string);
9849             color = getPixelColor(device, 600, 240);
9850             ok(color_match(color, ref_color_right, 18),
9851                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9852                test_data[i].in, color, ref_color_right, fmt_string);
9853             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9854             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9855         }
9856         IDirect3DSurface9_Release(surface);
9857     }
9858     IDirect3DSurface9_Release(target);
9859     IDirect3D9_Release(d3d);
9860 }
9861
9862 static void texop_range_test(IDirect3DDevice9 *device)
9863 {
9864     static const struct {
9865         float x, y, z;
9866         D3DCOLOR diffuse;
9867     } quad[] = {
9868         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9869         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9870         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9871         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9872     };
9873     HRESULT hr;
9874     IDirect3DTexture9 *texture;
9875     D3DLOCKED_RECT locked_rect;
9876     D3DCAPS9 caps;
9877     DWORD color;
9878
9879     /* We need ADD and SUBTRACT operations */
9880     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9881     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9882     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9883         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9884         return;
9885     }
9886     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9887         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9888         return;
9889     }
9890
9891     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9892     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9893     /* Stage 1: result = diffuse(=1.0) + diffuse
9894      * stage 2: result = result - tfactor(= 0.5)
9895      */
9896     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9897     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9898     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9899     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9900     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9901     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9902     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9903     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9904     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9905     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9906     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9907     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9908     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9909     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9910
9911     hr = IDirect3DDevice9_BeginScene(device);
9912     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9913     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9914     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9915     hr = IDirect3DDevice9_EndScene(device);
9916     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9917
9918     color = getPixelColor(device, 320, 240);
9919     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9920        color);
9921     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9922     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9923
9924     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9925     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9926     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9927     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9928     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9929     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9930     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9931     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9932     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9933
9934     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9935      * stage 2: result = result + diffuse(1.0)
9936      */
9937     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9938     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9939     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9940     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9941     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9942     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9943     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9944     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9945     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9946     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9947     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9948     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9949     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9950     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9951
9952     hr = IDirect3DDevice9_BeginScene(device);
9953     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9954     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9955     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9956     hr = IDirect3DDevice9_EndScene(device);
9957     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9958
9959     color = getPixelColor(device, 320, 240);
9960     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9961        color);
9962     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9963     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9964
9965     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9966     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9967     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9968     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9969     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9970     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9971     IDirect3DTexture9_Release(texture);
9972 }
9973
9974 static void alphareplicate_test(IDirect3DDevice9 *device) {
9975     struct vertex quad[] = {
9976         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9977         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9978         { -1.0,     1.0,    0.1,    0x80ff00ff },
9979         {  1.0,     1.0,    0.1,    0x80ff00ff },
9980     };
9981     HRESULT hr;
9982     DWORD color;
9983
9984     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9985     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9986
9987     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9988     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9989
9990     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9991     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9993     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9994
9995     hr = IDirect3DDevice9_BeginScene(device);
9996     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9997     if(SUCCEEDED(hr)) {
9998         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9999         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10000         hr = IDirect3DDevice9_EndScene(device);
10001         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10002     }
10003
10004     color = getPixelColor(device, 320, 240);
10005     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
10006        color);
10007     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10008     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
10009
10010     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10011     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10012
10013 }
10014
10015 static void dp3_alpha_test(IDirect3DDevice9 *device) {
10016     HRESULT hr;
10017     D3DCAPS9 caps;
10018     DWORD color;
10019     struct vertex quad[] = {
10020         { -1.0,    -1.0,    0.1,    0x408080c0 },
10021         {  1.0,    -1.0,    0.1,    0x408080c0 },
10022         { -1.0,     1.0,    0.1,    0x408080c0 },
10023         {  1.0,     1.0,    0.1,    0x408080c0 },
10024     };
10025
10026     memset(&caps, 0, sizeof(caps));
10027     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10028     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
10029     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
10030         skip("D3DTOP_DOTPRODUCT3 not supported\n");
10031         return;
10032     }
10033
10034     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10035     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10036
10037     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10038     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10039
10040     /* dp3_x4 r0, diffuse_bias, tfactor_bias
10041      * mov r0.a, diffuse.a
10042      * mov r0, r0.a
10043      *
10044      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
10045      * 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
10046      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
10047      */
10048     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
10049     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10050     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10051     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10052     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
10053     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10054     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10055     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10056     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10057     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10058     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10059     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10060     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
10061     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10062     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10063     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
10065     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10066
10067     hr = IDirect3DDevice9_BeginScene(device);
10068     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10069     if(SUCCEEDED(hr)) {
10070         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10071         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10072         hr = IDirect3DDevice9_EndScene(device);
10073         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10074     }
10075
10076     color = getPixelColor(device, 320, 240);
10077     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
10078        color);
10079     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10080     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10081
10082     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
10083     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10084     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
10085     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10086     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
10087     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
10088 }
10089
10090 static void zwriteenable_test(IDirect3DDevice9 *device) {
10091     HRESULT hr;
10092     DWORD color;
10093     struct vertex quad1[] = {
10094         { -1.0,  -1.0,  0.1,    0x00ff0000},
10095         { -1.0,   1.0,  0.1,    0x00ff0000},
10096         {  1.0,  -1.0,  0.1,    0x00ff0000},
10097         {  1.0,   1.0,  0.1,    0x00ff0000},
10098     };
10099     struct vertex quad2[] = {
10100         { -1.0,  -1.0,  0.9,    0x0000ff00},
10101         { -1.0,   1.0,  0.9,    0x0000ff00},
10102         {  1.0,  -1.0,  0.9,    0x0000ff00},
10103         {  1.0,   1.0,  0.9,    0x0000ff00},
10104     };
10105
10106     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
10107     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10108
10109     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10110     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10111     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10112     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10113     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10114     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10115     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10116     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10117
10118     hr = IDirect3DDevice9_BeginScene(device);
10119     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10120     if(SUCCEEDED(hr)) {
10121         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
10122          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
10123          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
10124          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
10125          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
10126          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
10127          */
10128         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10129         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10130         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10131         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10132         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10133         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10134
10135         hr = IDirect3DDevice9_EndScene(device);
10136         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10137     }
10138
10139     color = getPixelColor(device, 320, 240);
10140     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10141        color);
10142     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10143     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10144
10145     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10146     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10147 }
10148
10149 static void alphatest_test(IDirect3DDevice9 *device) {
10150 #define ALPHATEST_PASSED 0x0000ff00
10151 #define ALPHATEST_FAILED 0x00ff0000
10152     struct {
10153         D3DCMPFUNC  func;
10154         DWORD       color_less;
10155         DWORD       color_equal;
10156         DWORD       color_greater;
10157     } testdata[] = {
10158         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10159         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10160         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10161         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10162         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10163         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10164         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10165         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10166     };
10167     unsigned int i, j;
10168     HRESULT hr;
10169     DWORD color;
10170     struct vertex quad[] = {
10171         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10172         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10173         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10174         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10175     };
10176     D3DCAPS9 caps;
10177
10178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10179     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10180     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10181     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10182
10183     for(j = 0; j < 2; j++) {
10184         if(j == 1) {
10185             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10186              * the alpha test either for performance reasons(floating point RTs) or to work
10187              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10188              * codepath for ffp and shader in this case, and the test should cover both
10189              */
10190             IDirect3DPixelShader9 *ps;
10191             DWORD shader_code[] = {
10192                 0xffff0101,                                 /* ps_1_1           */
10193                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10194                 0x0000ffff                                  /* end              */
10195             };
10196             memset(&caps, 0, sizeof(caps));
10197             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10198             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10199             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10200                 break;
10201             }
10202
10203             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10204             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10205             IDirect3DDevice9_SetPixelShader(device, ps);
10206             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10207             IDirect3DPixelShader9_Release(ps);
10208         }
10209
10210         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10211             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10212             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10213
10214             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10215             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10216             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10217             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10218             hr = IDirect3DDevice9_BeginScene(device);
10219             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10220             if(SUCCEEDED(hr)) {
10221                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10222                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10223                 hr = IDirect3DDevice9_EndScene(device);
10224                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10225             }
10226             color = getPixelColor(device, 320, 240);
10227             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10228             color, testdata[i].color_less, testdata[i].func);
10229             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10230             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10231
10232             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10233             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10234             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10235             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10236             hr = IDirect3DDevice9_BeginScene(device);
10237             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10238             if(SUCCEEDED(hr)) {
10239                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10240                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10241                 hr = IDirect3DDevice9_EndScene(device);
10242                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10243             }
10244             color = getPixelColor(device, 320, 240);
10245             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10246             color, testdata[i].color_equal, testdata[i].func);
10247             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10248             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10249
10250             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10251             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10252             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10253             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10254             hr = IDirect3DDevice9_BeginScene(device);
10255             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10256             if(SUCCEEDED(hr)) {
10257                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10258                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10259                 hr = IDirect3DDevice9_EndScene(device);
10260                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10261             }
10262             color = getPixelColor(device, 320, 240);
10263             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10264             color, testdata[i].color_greater, testdata[i].func);
10265             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10266             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10267         }
10268     }
10269
10270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10272     IDirect3DDevice9_SetPixelShader(device, NULL);
10273     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10274 }
10275
10276 static void sincos_test(IDirect3DDevice9 *device) {
10277     const DWORD sin_shader_code[] = {
10278         0xfffe0200,                                                                 /* vs_2_0                       */
10279         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10280         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10281         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10282         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10283         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10284         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10285         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10286         0x0000ffff                                                                  /* end                          */
10287     };
10288     const DWORD cos_shader_code[] = {
10289         0xfffe0200,                                                                 /* vs_2_0                       */
10290         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10291         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10292         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10293         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10294         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10295         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10296         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10297         0x0000ffff                                                                  /* end                          */
10298     };
10299     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10300     HRESULT hr;
10301     struct {
10302         float x, y, z;
10303     } data[1280];
10304     unsigned int i;
10305     float sincosc1[4] = {D3DSINCOSCONST1};
10306     float sincosc2[4] = {D3DSINCOSCONST2};
10307
10308     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10309     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10310
10311     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10312     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10313     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10314     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10315     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10316     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10317     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10318     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10319     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10320     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10321
10322     /* Generate a point from -1 to 1 every 0.5 pixels */
10323     for(i = 0; i < 1280; i++) {
10324         data[i].x = (-640.0 + i) / 640.0;
10325         data[i].y = 0.0;
10326         data[i].z = 0.1;
10327     }
10328
10329     hr = IDirect3DDevice9_BeginScene(device);
10330     if(SUCCEEDED(hr)) {
10331         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10332         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10333         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10334         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10335
10336         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10337         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10338         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10339         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10340
10341         hr = IDirect3DDevice9_EndScene(device);
10342         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10343     }
10344     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10345     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10346     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10347
10348     IDirect3DDevice9_SetVertexShader(device, NULL);
10349     IDirect3DVertexShader9_Release(sin_shader);
10350     IDirect3DVertexShader9_Release(cos_shader);
10351 }
10352
10353 static void loop_index_test(IDirect3DDevice9 *device) {
10354     const DWORD shader_code[] = {
10355         0xfffe0200,                                                 /* vs_2_0                   */
10356         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10357         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10358         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10359         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10360         0x0000001d,                                                 /* endloop                  */
10361         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10362         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10363         0x0000ffff                                                  /* END                      */
10364     };
10365     IDirect3DVertexShader9 *shader;
10366     HRESULT hr;
10367     DWORD color;
10368     const float quad[] = {
10369         -1.0,   -1.0,   0.1,
10370          1.0,   -1.0,   0.1,
10371         -1.0,    1.0,   0.1,
10372          1.0,    1.0,   0.1
10373     };
10374     const float zero[4] = {0, 0, 0, 0};
10375     const float one[4] = {1, 1, 1, 1};
10376     int i0[4] = {2, 10, -3, 0};
10377     float values[4];
10378
10379     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10380     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10381     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10382     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10383     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10384     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10385     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10386     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10387
10388     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10389     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10390     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10391     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10392     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10393     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10394     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10395     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10396     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10397     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10398     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10399     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10400     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10401     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10402     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10403     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10404     values[0] = 1.0;
10405     values[1] = 1.0;
10406     values[2] = 0.0;
10407     values[3] = 0.0;
10408     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10409     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10410     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10411     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10412     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10413     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10414     values[0] = -1.0;
10415     values[1] = 0.0;
10416     values[2] = 0.0;
10417     values[3] = 0.0;
10418     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10419     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10420     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10421     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10422     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10423     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10424     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10425     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10426     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10427     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10428
10429     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10430     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10431
10432     hr = IDirect3DDevice9_BeginScene(device);
10433     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10434     if(SUCCEEDED(hr))
10435     {
10436         trace("going to draw index\n");
10437         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10438         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10439         hr = IDirect3DDevice9_EndScene(device);
10440         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10441     }
10442     color = getPixelColor(device, 320, 240);
10443     ok(color_match(color, 0x0000ff00, 1),
10444        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10447
10448     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10449     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10450     IDirect3DVertexShader9_Release(shader);
10451 }
10452
10453 static void sgn_test(IDirect3DDevice9 *device) {
10454     const DWORD shader_code[] = {
10455         0xfffe0200,                                                             /* vs_2_0                       */
10456         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10457         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10458         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10459         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10460         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10461         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10462         0x0000ffff                                                              /* end                          */
10463     };
10464     IDirect3DVertexShader9 *shader;
10465     HRESULT hr;
10466     DWORD color;
10467     const float quad[] = {
10468         -1.0,   -1.0,   0.1,
10469          1.0,   -1.0,   0.1,
10470         -1.0,    1.0,   0.1,
10471          1.0,    1.0,   0.1
10472     };
10473
10474     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10475     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10476     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10477     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10478     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10479     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10480     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10481     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10482
10483     hr = IDirect3DDevice9_BeginScene(device);
10484     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10485     if(SUCCEEDED(hr))
10486     {
10487         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10488         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10489         hr = IDirect3DDevice9_EndScene(device);
10490         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10491     }
10492     color = getPixelColor(device, 320, 240);
10493     ok(color_match(color, 0x008000ff, 1),
10494        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10495     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10496     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10497
10498     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10499     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10500     IDirect3DVertexShader9_Release(shader);
10501 }
10502
10503 static void viewport_test(IDirect3DDevice9 *device) {
10504     HRESULT hr;
10505     DWORD color;
10506     D3DVIEWPORT9 vp, old_vp;
10507     const float quad[] =
10508     {
10509         -0.5,   -0.5,   0.1,
10510          0.5,   -0.5,   0.1,
10511         -0.5,    0.5,   0.1,
10512          0.5,    0.5,   0.1
10513     };
10514
10515     memset(&old_vp, 0, sizeof(old_vp));
10516     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10517     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10518
10519     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10520     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10521
10522     /* Test a viewport with Width and Height bigger than the surface dimensions
10523      *
10524      * TODO: Test Width < surface.width, but X + Width > surface.width
10525      * TODO: Test Width < surface.width, what happens with the height?
10526      */
10527     memset(&vp, 0, sizeof(vp));
10528     vp.X = 0;
10529     vp.Y = 0;
10530     vp.Width = 10000;
10531     vp.Height = 10000;
10532     vp.MinZ = 0.0;
10533     vp.MaxZ = 0.0;
10534     hr = IDirect3DDevice9_SetViewport(device, &vp);
10535     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10536
10537     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10538     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10539     hr = IDirect3DDevice9_BeginScene(device);
10540     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10541     if(SUCCEEDED(hr))
10542     {
10543         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10544         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10545         hr = IDirect3DDevice9_EndScene(device);
10546         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10547     }
10548
10549     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10550     color = getPixelColor(device, 158, 118);
10551     ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10552     color = getPixelColor(device, 162, 118);
10553     ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10554     color = getPixelColor(device, 158, 122);
10555     ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10556     color = getPixelColor(device, 162, 122);
10557     ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10558
10559     color = getPixelColor(device, 478, 358);
10560     ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10561     color = getPixelColor(device, 482, 358);
10562     ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10563     color = getPixelColor(device, 478, 362);
10564     ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10565     color = getPixelColor(device, 482, 362);
10566     ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10567
10568     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10569     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10570
10571     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10572     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10573 }
10574
10575 /* This test tests depth clamping / clipping behaviour:
10576  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10577  *   minimum/maximum z value.
10578  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10579  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10580  *   - Pretransformed vertices behave the same as regular vertices.
10581  */
10582 static void depth_clamp_test(IDirect3DDevice9 *device)
10583 {
10584     const struct tvertex quad1[] =
10585     {
10586         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10587         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10588         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10589         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10590     };
10591     const struct tvertex quad2[] =
10592     {
10593         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10594         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10595         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10596         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10597     };
10598     const struct vertex quad3[] =
10599     {
10600         {-0.65, 0.55,  5.0f,      0xffffffff},
10601         {-0.35, 0.55,  5.0f,      0xffffffff},
10602         {-0.65, 0.15,  5.0f,      0xffffffff},
10603         {-0.35, 0.15,  5.0f,      0xffffffff},
10604     };
10605     const struct vertex quad4[] =
10606     {
10607         {-0.87, 0.83, 10.0f,      0xffffffff},
10608         {-0.65, 0.83, 10.0f,      0xffffffff},
10609         {-0.87, 0.55, 10.0f,      0xffffffff},
10610         {-0.65, 0.55, 10.0f,      0xffffffff},
10611     };
10612     const struct vertex quad5[] =
10613     {
10614         { -0.5,  0.5, 10.0f,      0xff14f914},
10615         {  0.5,  0.5, 10.0f,      0xff14f914},
10616         { -0.5, -0.5, 10.0f,      0xff14f914},
10617         {  0.5, -0.5, 10.0f,      0xff14f914},
10618     };
10619     const struct tvertex quad6[] =
10620     {
10621         {    0,  120, 10.0f, 1.0, 0xfff91414},
10622         {  640,  120, 10.0f, 1.0, 0xfff91414},
10623         {    0,  180, 10.0f, 1.0, 0xfff91414},
10624         {  640,  180, 10.0f, 1.0, 0xfff91414},
10625     };
10626
10627     D3DVIEWPORT9 vp;
10628     D3DCOLOR color;
10629     HRESULT hr;
10630
10631     vp.X = 0;
10632     vp.Y = 0;
10633     vp.Width = 640;
10634     vp.Height = 480;
10635     vp.MinZ = 0.0;
10636     vp.MaxZ = 7.5;
10637
10638     hr = IDirect3DDevice9_SetViewport(device, &vp);
10639     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10640
10641     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10642     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10643
10644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10645     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10647     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10648     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10649     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10651     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10652
10653     hr = IDirect3DDevice9_BeginScene(device);
10654     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10655
10656     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10657     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10658
10659     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10660     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10661     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10662     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10663
10664     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10665     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10666
10667     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10668     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10669     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10670     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10671
10672     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10673     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10674
10675     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10676     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10677
10678     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10679     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10680
10681     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10682     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10683
10684     hr = IDirect3DDevice9_EndScene(device);
10685     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10686
10687     color = getPixelColor(device, 75, 75);
10688     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10689     color = getPixelColor(device, 150, 150);
10690     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10691     color = getPixelColor(device, 320, 240);
10692     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10693     color = getPixelColor(device, 320, 330);
10694     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10695     color = getPixelColor(device, 320, 330);
10696     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10697
10698     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10699     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10700
10701     vp.MinZ = 0.0;
10702     vp.MaxZ = 1.0;
10703     hr = IDirect3DDevice9_SetViewport(device, &vp);
10704     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10705 }
10706
10707 START_TEST(visual)
10708 {
10709     IDirect3DDevice9 *device_ptr;
10710     D3DCAPS9 caps;
10711     HRESULT hr;
10712     DWORD color;
10713
10714     d3d9_handle = LoadLibraryA("d3d9.dll");
10715     if (!d3d9_handle)
10716     {
10717         skip("Could not load d3d9.dll\n");
10718         return;
10719     }
10720
10721     device_ptr = init_d3d9();
10722     if (!device_ptr)
10723     {
10724         skip("Creating the device failed\n");
10725         return;
10726     }
10727
10728     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
10729
10730     /* Check for the reliability of the returned data */
10731     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
10732     if(FAILED(hr))
10733     {
10734         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10735         goto cleanup;
10736     }
10737
10738     color = getPixelColor(device_ptr, 1, 1);
10739     if(color !=0x00ff0000)
10740     {
10741         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10742         goto cleanup;
10743     }
10744     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10745
10746     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
10747     if(FAILED(hr))
10748     {
10749         skip("Clear failed, can't assure correctness of the test results, skipping\n");
10750         goto cleanup;
10751     }
10752
10753     color = getPixelColor(device_ptr, 639, 479);
10754     if(color != 0x0000ddee)
10755     {
10756         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
10757         goto cleanup;
10758     }
10759     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
10760
10761     /* Now execute the real tests */
10762     depth_clamp_test(device_ptr);
10763     stretchrect_test(device_ptr);
10764     lighting_test(device_ptr);
10765     clear_test(device_ptr);
10766     fog_test(device_ptr);
10767     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
10768     {
10769         test_cube_wrap(device_ptr);
10770     } else {
10771         skip("No cube texture support\n");
10772     }
10773     z_range_test(device_ptr);
10774     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
10775     {
10776         maxmip_test(device_ptr);
10777     }
10778     else
10779     {
10780         skip("No mipmap support\n");
10781     }
10782     offscreen_test(device_ptr);
10783     alpha_test(device_ptr);
10784     shademode_test(device_ptr);
10785     srgbtexture_test(device_ptr);
10786     release_buffer_test(device_ptr);
10787     float_texture_test(device_ptr);
10788     g16r16_texture_test(device_ptr);
10789     pixelshader_blending_test(device_ptr);
10790     texture_transform_flags_test(device_ptr);
10791     autogen_mipmap_test(device_ptr);
10792     fixed_function_decl_test(device_ptr);
10793     conditional_np2_repeat_test(device_ptr);
10794     fixed_function_bumpmap_test(device_ptr);
10795     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
10796         stencil_cull_test(device_ptr);
10797     } else {
10798         skip("No two sided stencil support\n");
10799     }
10800     pointsize_test(device_ptr);
10801     tssargtemp_test(device_ptr);
10802     np2_stretch_rect_test(device_ptr);
10803     yuv_color_test(device_ptr);
10804     zwriteenable_test(device_ptr);
10805     alphatest_test(device_ptr);
10806     viewport_test(device_ptr);
10807
10808     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10809     {
10810         test_constant_clamp_vs(device_ptr);
10811         test_compare_instructions(device_ptr);
10812     }
10813     else skip("No vs_1_1 support\n");
10814
10815     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
10816     {
10817         test_mova(device_ptr);
10818         loop_index_test(device_ptr);
10819         sincos_test(device_ptr);
10820         sgn_test(device_ptr);
10821         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10822             test_vshader_input(device_ptr);
10823             test_vshader_float16(device_ptr);
10824             stream_test(device_ptr);
10825         } else {
10826             skip("No vs_3_0 support\n");
10827         }
10828     }
10829     else skip("No vs_2_0 support\n");
10830
10831     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10832     {
10833         fog_with_shader_test(device_ptr);
10834         fog_srgbwrite_test(device_ptr);
10835     }
10836     else skip("No vs_1_1 and ps_1_1 support\n");
10837
10838     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
10839     {
10840         texbem_test(device_ptr);
10841         texdepth_test(device_ptr);
10842         texkill_test(device_ptr);
10843         x8l8v8u8_test(device_ptr);
10844         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
10845             constant_clamp_ps_test(device_ptr);
10846             cnd_test(device_ptr);
10847             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
10848                 dp2add_ps_test(device_ptr);
10849                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
10850                     nested_loop_test(device_ptr);
10851                     fixed_function_varying_test(device_ptr);
10852                     vFace_register_test(device_ptr);
10853                     vpos_register_test(device_ptr);
10854                     multiple_rendertargets_test(device_ptr);
10855                     if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10856                         vshader_version_varying_test(device_ptr);
10857                         pshader_version_varying_test(device_ptr);
10858                     } else {
10859                         skip("No vs_3_0 support\n");
10860                     }
10861                 } else {
10862                     skip("No ps_3_0 support\n");
10863                 }
10864             } else {
10865                 skip("No ps_2_0 support\n");
10866             }
10867         }
10868     }
10869     else skip("No ps_1_1 support\n");
10870
10871     texop_test(device_ptr);
10872     texop_range_test(device_ptr);
10873     alphareplicate_test(device_ptr);
10874     dp3_alpha_test(device_ptr);
10875
10876 cleanup:
10877     if(device_ptr) {
10878         D3DPRESENT_PARAMETERS present_parameters;
10879         IDirect3DSwapChain9 *swapchain;
10880         ULONG ref;
10881
10882         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10883         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10884         IDirect3DSwapChain9_Release(swapchain);
10885         ref = IDirect3DDevice9_Release(device_ptr);
10886         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
10887         DestroyWindow(present_parameters.hDeviceWindow);
10888     }
10889 }