wined3d: Disallow empty surfaces.
[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 0x%08x, expected 0x00ff0000.\n", color);
351     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
352     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
353     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
354     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
355     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
356     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
357
358     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
359
360     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
361     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
362     memset(&material, 0, sizeof(material));
363     material.Diffuse.r = 0.0;
364     material.Diffuse.g = 0.0;
365     material.Diffuse.b = 0.0;
366     material.Diffuse.a = 1.0;
367     material.Ambient.r = 0.0;
368     material.Ambient.g = 0.0;
369     material.Ambient.b = 0.0;
370     material.Ambient.a = 0.0;
371     material.Specular.r = 0.0;
372     material.Specular.g = 0.0;
373     material.Specular.b = 0.0;
374     material.Specular.a = 0.0;
375     material.Emissive.r = 0.0;
376     material.Emissive.g = 0.0;
377     material.Emissive.b = 0.0;
378     material.Emissive.a = 0.0;
379     material.Power = 0.0;
380     IDirect3DDevice9_SetMaterial(device, &material);
381     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
382
383     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
384     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
385     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
386     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
387
388     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
389     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
390     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
391     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
392     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
393     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
394     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
395     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
396
397     hr = IDirect3DDevice9_BeginScene(device);
398     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
399     if(SUCCEEDED(hr)) {
400         struct vertex lighting_test[] = {
401             {-1.0,   -1.0,   0.1,    0x8000ff00},
402             { 1.0,   -1.0,   0.1,    0x80000000},
403             {-1.0,    1.0,   0.1,    0x8000ff00},
404             { 1.0,    1.0,   0.1,    0x80000000}
405         };
406         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
407         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
408         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
409         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
410
411         hr = IDirect3DDevice9_EndScene(device);
412         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
413     }
414
415     color = getPixelColor(device, 320, 240);
416     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
417     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
418
419     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
421     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
422     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
423     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
424     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
425     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
426     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
427     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
428     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
429     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
430     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
431 }
432
433 static void clear_test(IDirect3DDevice9 *device)
434 {
435     /* Tests the correctness of clearing parameters */
436     HRESULT hr;
437     D3DRECT rect[2];
438     D3DRECT rect_negneg;
439     DWORD color;
440     D3DVIEWPORT9 old_vp, vp;
441     RECT scissor;
442     DWORD oldColorWrite;
443     BOOL invalid_clear_failed = FALSE;
444
445     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
446     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
447
448     /* Positive x, negative y */
449     rect[0].x1 = 0;
450     rect[0].y1 = 480;
451     rect[0].x2 = 320;
452     rect[0].y2 = 240;
453
454     /* Positive x, positive y */
455     rect[1].x1 = 0;
456     rect[1].y1 = 0;
457     rect[1].x2 = 320;
458     rect[1].y2 = 240;
459     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
460      * returns D3D_OK, but ignores the rectangle silently
461      */
462     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
463     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
464     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
465
466     /* negative x, negative y */
467     rect_negneg.x1 = 640;
468     rect_negneg.y1 = 240;
469     rect_negneg.x2 = 320;
470     rect_negneg.y2 = 0;
471     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
472     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
473     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
474
475     color = getPixelColor(device, 160, 360); /* lower left quad */
476     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
477     color = getPixelColor(device, 160, 120); /* upper left quad */
478     if(invalid_clear_failed) {
479         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
480         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
481     } else {
482         /* If the negative rectangle was dropped silently, the correct ones are cleared */
483         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
484     }
485     color = getPixelColor(device, 480, 360); /* lower right quad  */
486     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
487     color = getPixelColor(device, 480, 120); /* upper right quad */
488     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
489
490     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
491
492     /* Test how the viewport affects clears */
493     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
494     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
495     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
496     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
497
498     vp.X = 160;
499     vp.Y = 120;
500     vp.Width = 160;
501     vp.Height = 120;
502     vp.MinZ = 0.0;
503     vp.MaxZ = 1.0;
504     hr = IDirect3DDevice9_SetViewport(device, &vp);
505     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
506     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
507     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
508
509     vp.X = 320;
510     vp.Y = 240;
511     vp.Width = 320;
512     vp.Height = 240;
513     vp.MinZ = 0.0;
514     vp.MaxZ = 1.0;
515     hr = IDirect3DDevice9_SetViewport(device, &vp);
516     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
517     rect[0].x1 = 160;
518     rect[0].y1 = 120;
519     rect[0].x2 = 480;
520     rect[0].y2 = 360;
521     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
522     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
523
524     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
525     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
526
527     color = getPixelColor(device, 158, 118);
528     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
529     color = getPixelColor(device, 162, 118);
530     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
531     color = getPixelColor(device, 158, 122);
532     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
533     color = getPixelColor(device, 162, 122);
534     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
535
536     color = getPixelColor(device, 318, 238);
537     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
538     color = getPixelColor(device, 322, 238);
539     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
540     color = getPixelColor(device, 318, 242);
541     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
542     color = getPixelColor(device, 322, 242);
543     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
544
545     color = getPixelColor(device, 478, 358);
546     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
547     color = getPixelColor(device, 482, 358);
548     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
549     color = getPixelColor(device, 478, 362);
550     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
551     color = getPixelColor(device, 482, 362);
552     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
553
554     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
555
556     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
557     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
558
559     scissor.left = 160;
560     scissor.right = 480;
561     scissor.top = 120;
562     scissor.bottom = 360;
563     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
564     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
566     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
567
568     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
569     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
570     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
571     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
572
573     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
574     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
575
576     color = getPixelColor(device, 158, 118);
577     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
578     color = getPixelColor(device, 162, 118);
579     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
580     color = getPixelColor(device, 158, 122);
581     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
582     color = getPixelColor(device, 162, 122);
583     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
584
585     color = getPixelColor(device, 158, 358);
586     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
587     color = getPixelColor(device, 162, 358);
588     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
589     color = getPixelColor(device, 158, 358);
590     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
591     color = getPixelColor(device, 162, 362);
592     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
593
594     color = getPixelColor(device, 478, 118);
595     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
596     color = getPixelColor(device, 478, 122);
597     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
598     color = getPixelColor(device, 482, 122);
599     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
600     color = getPixelColor(device, 482, 358);
601     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
602
603     color = getPixelColor(device, 478, 358);
604     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
605     color = getPixelColor(device, 478, 362);
606     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
607     color = getPixelColor(device, 482, 358);
608     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
609     color = getPixelColor(device, 482, 362);
610     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
611
612     color = getPixelColor(device, 318, 238);
613     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
614     color = getPixelColor(device, 318, 242);
615     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
616     color = getPixelColor(device, 322, 238);
617     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
618     color = getPixelColor(device, 322, 242);
619     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
620
621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
622
623     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
624     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
625     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
626     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
627
628     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
629     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
630
631     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
632     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
633
634     /* Colorwriteenable does not affect the clear */
635     color = getPixelColor(device, 320, 240);
636     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
637
638     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
639 }
640
641 static void color_fill_test(IDirect3DDevice9 *device)
642 {
643     HRESULT hr;
644     IDirect3DSurface9 *backbuffer = NULL;
645     IDirect3DSurface9 *rt_surface = NULL;
646     IDirect3DSurface9 *offscreen_surface = NULL;
647     DWORD fill_color, color;
648
649     /* Test ColorFill on a the backbuffer (should pass) */
650     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
651     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
652     if(backbuffer)
653     {
654         fill_color = 0x112233;
655         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
656
657         color = getPixelColor(device, 0, 0);
658         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
659
660         IDirect3DSurface9_Release(backbuffer);
661     }
662
663     /* Test ColorFill on a render target surface (should pass) */
664     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
665     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
666     if(rt_surface)
667     {
668         fill_color = 0x445566;
669         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
670
671         color = getPixelColorFromSurface(rt_surface, 0, 0);
672         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
673
674         IDirect3DSurface9_Release(rt_surface);
675     }
676
677     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
678     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
679             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
680     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
681     if(offscreen_surface)
682     {
683         fill_color = 0x778899;
684         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
685
686         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
687         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
688
689         IDirect3DSurface9_Release(offscreen_surface);
690     }
691
692     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
693     offscreen_surface = NULL;
694     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
695             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
696     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
697     if(offscreen_surface)
698     {
699         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
700         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
701
702         IDirect3DSurface9_Release(offscreen_surface);
703     }
704 }
705
706 typedef struct {
707     float in[4];
708     DWORD out;
709 } test_data_t;
710
711 /*
712  *  c7      mova    ARGB            mov     ARGB
713  * -2.4     -2      0x00ffff00      -3      0x00ff0000
714  * -1.6     -2      0x00ffff00      -2      0x00ffff00
715  * -0.4      0      0x0000ffff      -1      0x0000ff00
716  *  0.4      0      0x0000ffff       0      0x0000ffff
717  *  1.6      2      0x00ff00ff       1      0x000000ff
718  *  2.4      2      0x00ff00ff       2      0x00ff00ff
719  */
720 static void test_mova(IDirect3DDevice9 *device)
721 {
722     static const DWORD mova_test[] = {
723         0xfffe0200,                                                             /* vs_2_0                       */
724         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
725         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
726         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
727         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
728         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
729         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
730         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
731         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
732         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
733         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
734         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
735         0x0000ffff                                                              /* END                          */
736     };
737     static const DWORD mov_test[] = {
738         0xfffe0101,                                                             /* vs_1_1                       */
739         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
740         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
741         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
742         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
743         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
744         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
745         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
746         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
747         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
748         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
749         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
750         0x0000ffff                                                              /* END                          */
751     };
752
753     static const test_data_t test_data[2][6] = {
754         {
755             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
756             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
757             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
758             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
759             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
760             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
761         },
762         {
763             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
764             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
765             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
766             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
767             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
768             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
769         }
770     };
771
772     static const float quad[][3] = {
773         {-1.0f, -1.0f, 0.0f},
774         {-1.0f,  1.0f, 0.0f},
775         { 1.0f, -1.0f, 0.0f},
776         { 1.0f,  1.0f, 0.0f},
777     };
778
779     static const D3DVERTEXELEMENT9 decl_elements[] = {
780         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
781         D3DDECL_END()
782     };
783
784     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
785     IDirect3DVertexShader9 *mova_shader = NULL;
786     IDirect3DVertexShader9 *mov_shader = NULL;
787     HRESULT hr;
788     UINT i, j;
789
790     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
791     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
792     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
793     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
794     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
795     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
796     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
797     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
798
799     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
800     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
801     for(j = 0; j < 2; ++j)
802     {
803         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
804         {
805             DWORD color;
806
807             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
808             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
809
810             hr = IDirect3DDevice9_BeginScene(device);
811             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
812
813             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
814             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
815
816             hr = IDirect3DDevice9_EndScene(device);
817             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
818
819             color = getPixelColor(device, 320, 240);
820             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
821                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
822
823             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
824             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
825
826             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
827             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
828         }
829         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
830         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
831     }
832
833     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
834     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
835
836     IDirect3DVertexDeclaration9_Release(vertex_declaration);
837     IDirect3DVertexShader9_Release(mova_shader);
838     IDirect3DVertexShader9_Release(mov_shader);
839 }
840
841 struct sVertex {
842     float x, y, z;
843     DWORD diffuse;
844     DWORD specular;
845 };
846
847 struct sVertexT {
848     float x, y, z, rhw;
849     DWORD diffuse;
850     DWORD specular;
851 };
852
853 static void fog_test(IDirect3DDevice9 *device)
854 {
855     HRESULT hr;
856     D3DCOLOR color;
857     float start = 0.0f, end = 1.0f;
858     D3DCAPS9 caps;
859     int i;
860
861     /* Gets full z based fog with linear fog, no fog with specular color */
862     struct sVertex unstransformed_1[] = {
863         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
864         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
865         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
866         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
867     };
868     /* Ok, I am too lazy to deal with transform matrices */
869     struct sVertex unstransformed_2[] = {
870         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
871         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
872         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
873         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
874     };
875     /* Untransformed ones. Give them a different diffuse color to make the test look
876      * nicer. It also makes making sure that they are drawn correctly easier.
877      */
878     struct sVertexT transformed_1[] = {
879         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
880         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
881         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
882         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
883     };
884     struct sVertexT transformed_2[] = {
885         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
886         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
887         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
888         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
889     };
890     struct vertex rev_fog_quads[] = {
891        {-1.0,   -1.0,   0.1,    0x000000ff},
892        {-1.0,    0.0,   0.1,    0x000000ff},
893        { 0.0,    0.0,   0.1,    0x000000ff},
894        { 0.0,   -1.0,   0.1,    0x000000ff},
895
896        { 0.0,   -1.0,   0.9,    0x000000ff},
897        { 0.0,    0.0,   0.9,    0x000000ff},
898        { 1.0,    0.0,   0.9,    0x000000ff},
899        { 1.0,   -1.0,   0.9,    0x000000ff},
900
901        { 0.0,    0.0,   0.4,    0x000000ff},
902        { 0.0,    1.0,   0.4,    0x000000ff},
903        { 1.0,    1.0,   0.4,    0x000000ff},
904        { 1.0,    0.0,   0.4,    0x000000ff},
905
906        {-1.0,    0.0,   0.7,    0x000000ff},
907        {-1.0,    1.0,   0.7,    0x000000ff},
908        { 0.0,    1.0,   0.7,    0x000000ff},
909        { 0.0,    0.0,   0.7,    0x000000ff},
910     };
911     WORD Indices[] = {0, 1, 2, 2, 3, 0};
912
913     memset(&caps, 0, sizeof(caps));
914     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
915     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
916     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
917     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
918
919     /* Setup initial states: No lighting, fog on, fog color */
920     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
921     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
922     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
923     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
924     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
925     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
926
927     /* First test: Both table fog and vertex fog off */
928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
929     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
930     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
931     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
932
933     /* Start = 0, end = 1. Should be default, but set them */
934     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
935     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
936     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
937     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
938
939     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
940     {
941         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
942         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
943         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
944         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
945                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
946                                                      sizeof(unstransformed_1[0]));
947         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
948
949         /* That makes it use the Z value */
950         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
951         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
952         /* Untransformed, vertex fog != none (or table fog != none):
953          * Use the Z value as input into the equation
954          */
955         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
956                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
957                                                      sizeof(unstransformed_1[0]));
958         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
959
960         /* transformed verts */
961         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
962         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
963         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
964         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
965                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
966                                                      sizeof(transformed_1[0]));
967         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
968
969         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
970         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
971         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
972          * equation
973          */
974         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
976                                                      sizeof(transformed_2[0]));
977         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
978
979         hr = IDirect3DDevice9_EndScene(device);
980         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
981     }
982     else
983     {
984         ok(FALSE, "BeginScene failed\n");
985     }
986
987     color = getPixelColor(device, 160, 360);
988     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
989     color = getPixelColor(device, 160, 120);
990     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
991     color = getPixelColor(device, 480, 120);
992     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
993     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
994     {
995         color = getPixelColor(device, 480, 360);
996         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
997     }
998     else
999     {
1000         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1001          * The settings above result in no fogging with vertex fog
1002          */
1003         color = getPixelColor(device, 480, 120);
1004         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1005         trace("Info: Table fog not supported by this device\n");
1006     }
1007     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1008
1009     /* Now test the special case fogstart == fogend */
1010     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1011     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1012
1013     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1014     {
1015         start = 512;
1016         end = 512;
1017         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1018         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1019         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1020         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1021
1022         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1023         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1024         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1025         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1026         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1027         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1028
1029         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1030          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1031          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1032          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1033          * color and has fixed fogstart and fogend.
1034          */
1035         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1036                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1037                 sizeof(unstransformed_1[0]));
1038         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1039         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1040                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1041                 sizeof(unstransformed_1[0]));
1042         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1043
1044         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1045         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1046         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1047         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1048                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1049                 sizeof(transformed_1[0]));
1050         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1051
1052         hr = IDirect3DDevice9_EndScene(device);
1053         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1054     }
1055     else
1056     {
1057         ok(FALSE, "BeginScene failed\n");
1058     }
1059     color = getPixelColor(device, 160, 360);
1060     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1061     color = getPixelColor(device, 160, 120);
1062     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1063     color = getPixelColor(device, 480, 120);
1064     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1065     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1066
1067     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1068      * but without shaders it seems to work everywhere
1069      */
1070     end = 0.2;
1071     start = 0.8;
1072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1073     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1075     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1076     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1077     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1078
1079     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1080      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1081      * so skip this for now
1082      */
1083     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1084         const char *mode = (i ? "table" : "vertex");
1085         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1086         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1087         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1088         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1089         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1090         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1091         hr = IDirect3DDevice9_BeginScene(device);
1092         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1093         if(SUCCEEDED(hr)) {
1094             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1095                                 4,  5,  6,  6,  7, 4,
1096                                 8,  9, 10, 10, 11, 8,
1097                             12, 13, 14, 14, 15, 12};
1098
1099             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1100                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1101                     sizeof(rev_fog_quads[0]));
1102             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1103
1104             hr = IDirect3DDevice9_EndScene(device);
1105             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1106         }
1107         color = getPixelColor(device, 160, 360);
1108         ok(color_match(color, 0x0000ff00, 1),
1109                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1110
1111         color = getPixelColor(device, 160, 120);
1112         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1113                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1114
1115         color = getPixelColor(device, 480, 120);
1116         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1117                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1118
1119         color = getPixelColor(device, 480, 360);
1120         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1121
1122         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1123
1124         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1125             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1126             break;
1127         }
1128     }
1129     /* Turn off the fog master switch to avoid confusing other tests */
1130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1131     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1132     start = 0.0;
1133     end = 1.0;
1134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1135     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1136     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1137     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1138     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1139     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1140     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1141     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1142 }
1143
1144 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1145  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1146  * regardless of the actual addressing mode set. The way this test works is
1147  * that we sample in one of the corners of the cubemap with filtering enabled,
1148  * and check the interpolated color. There are essentially two reasonable
1149  * things an implementation can do: Either pick one of the faces and
1150  * interpolate the edge texel with itself (i.e., clamp within the face), or
1151  * interpolate between the edge texels of the three involved faces. It should
1152  * never involve the border color or the other side (texcoord wrapping) of a
1153  * face in the interpolation. */
1154 static void test_cube_wrap(IDirect3DDevice9 *device)
1155 {
1156     static const float quad[][6] = {
1157         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1158         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1159         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1160         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1161     };
1162
1163     static const D3DVERTEXELEMENT9 decl_elements[] = {
1164         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1165         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1166         D3DDECL_END()
1167     };
1168
1169     static const struct {
1170         D3DTEXTUREADDRESS mode;
1171         const char *name;
1172     } address_modes[] = {
1173         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1174         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1175         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1176         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1177         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1178     };
1179
1180     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1181     IDirect3DCubeTexture9 *texture = NULL;
1182     IDirect3DSurface9 *surface = NULL;
1183     IDirect3DSurface9 *face_surface;
1184     D3DLOCKED_RECT locked_rect;
1185     HRESULT hr;
1186     UINT x;
1187     INT y, face;
1188
1189     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1190     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1191     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1192     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1193
1194     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1195             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1196     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1197
1198     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1199             D3DPOOL_DEFAULT, &texture, NULL);
1200     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1201
1202     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1203     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1204
1205     for (y = 0; y < 128; ++y)
1206     {
1207         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1208         for (x = 0; x < 64; ++x)
1209         {
1210             *ptr++ = 0xff0000ff;
1211         }
1212         for (x = 64; x < 128; ++x)
1213         {
1214             *ptr++ = 0xffff0000;
1215         }
1216     }
1217
1218     hr = IDirect3DSurface9_UnlockRect(surface);
1219     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1220
1221     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1222     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1223
1224     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1225     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1226
1227     IDirect3DSurface9_Release(face_surface);
1228
1229     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1230     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1231
1232     for (y = 0; y < 128; ++y)
1233     {
1234         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1235         for (x = 0; x < 64; ++x)
1236         {
1237             *ptr++ = 0xffff0000;
1238         }
1239         for (x = 64; x < 128; ++x)
1240         {
1241             *ptr++ = 0xff0000ff;
1242         }
1243     }
1244
1245     hr = IDirect3DSurface9_UnlockRect(surface);
1246     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1247
1248     /* Create cube faces */
1249     for (face = 1; face < 6; ++face)
1250     {
1251         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1252         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1253
1254         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1255         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1256
1257         IDirect3DSurface9_Release(face_surface);
1258     }
1259
1260     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1261     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1262
1263     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1264     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1265     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1266     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1267     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1268     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1269
1270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1272
1273     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1274     {
1275         DWORD color;
1276
1277         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1278         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1279         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1280         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1281
1282         hr = IDirect3DDevice9_BeginScene(device);
1283         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1284
1285         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1286         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1287
1288         hr = IDirect3DDevice9_EndScene(device);
1289         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1290
1291         color = getPixelColor(device, 320, 240);
1292         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1293                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1294                 color, address_modes[x].name);
1295
1296         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1297         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1298
1299         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1300         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1301     }
1302
1303     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1305
1306     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1307     IDirect3DCubeTexture9_Release(texture);
1308     IDirect3DSurface9_Release(surface);
1309 }
1310
1311 static void offscreen_test(IDirect3DDevice9 *device)
1312 {
1313     HRESULT hr;
1314     IDirect3DTexture9 *offscreenTexture = NULL;
1315     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1316     DWORD color;
1317
1318     static const float quad[][5] = {
1319         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1320         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1321         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1322         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1323     };
1324
1325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1326     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1327
1328     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1329     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1330     if(!offscreenTexture) {
1331         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1332         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1333         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1334         if(!offscreenTexture) {
1335             skip("Cannot create an offscreen render target\n");
1336             goto out;
1337         }
1338     }
1339
1340     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1341     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1342     if(!backbuffer) {
1343         goto out;
1344     }
1345
1346     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1347     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1348     if(!offscreen) {
1349         goto out;
1350     }
1351
1352     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1353     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1354
1355     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1356     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1357     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1358     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1359     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1360     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1361     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1362     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1363     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1364     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1365
1366     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1367         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1368         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1369         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1370         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1371
1372         /* Draw without textures - Should result in a white quad */
1373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1374         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1375
1376         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1377         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1378         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1379         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1380
1381         /* This time with the texture */
1382         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1383         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1384
1385         IDirect3DDevice9_EndScene(device);
1386     }
1387
1388     /* Center quad - should be white */
1389     color = getPixelColor(device, 320, 240);
1390     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1391     /* Some quad in the cleared part of the texture */
1392     color = getPixelColor(device, 170, 240);
1393     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1394     /* Part of the originally cleared back buffer */
1395     color = getPixelColor(device, 10, 10);
1396     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1397     if(0) {
1398         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1399          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1400          * the offscreen rendering mode this test would succeed or fail
1401          */
1402         color = getPixelColor(device, 10, 470);
1403         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1404     }
1405
1406     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1407
1408 out:
1409     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1410     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1411
1412     /* restore things */
1413     if(backbuffer) {
1414         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1415         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1416         IDirect3DSurface9_Release(backbuffer);
1417     }
1418     if(offscreenTexture) {
1419         IDirect3DTexture9_Release(offscreenTexture);
1420     }
1421     if(offscreen) {
1422         IDirect3DSurface9_Release(offscreen);
1423     }
1424 }
1425
1426 /* This test tests fog in combination with shaders.
1427  * What's tested: linear fog (vertex and table) with pixel shader
1428  *                linear table fog with non foggy vertex shader
1429  *                vertex fog with foggy vertex shader, non-linear
1430  *                fog with shader, non-linear fog with foggy shader,
1431  *                linear table fog with foggy shader
1432  */
1433 static void fog_with_shader_test(IDirect3DDevice9 *device)
1434 {
1435     HRESULT hr;
1436     DWORD color;
1437     union {
1438         float f;
1439         DWORD i;
1440     } start, end;
1441     unsigned int i, j;
1442
1443     /* basic vertex shader without fog computation ("non foggy") */
1444     static const DWORD vertex_shader_code1[] = {
1445         0xfffe0101,                                                             /* vs_1_1                       */
1446         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1447         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1448         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1449         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1450         0x0000ffff
1451     };
1452     /* basic vertex shader with reversed fog computation ("foggy") */
1453     static const DWORD vertex_shader_code2[] = {
1454         0xfffe0101,                                                             /* vs_1_1                        */
1455         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1456         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1457         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1458         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1459         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1460         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1461         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1462         0x0000ffff
1463     };
1464     /* basic pixel shader */
1465     static const DWORD pixel_shader_code[] = {
1466         0xffff0101,                                                             /* ps_1_1     */
1467         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1468         0x0000ffff
1469     };
1470
1471     static struct vertex quad[] = {
1472         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1473         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1474         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1475         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1476     };
1477
1478     static const D3DVERTEXELEMENT9 decl_elements[] = {
1479         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1480         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1481         D3DDECL_END()
1482     };
1483
1484     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1485     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1486     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1487
1488     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1489     static const struct test_data_t {
1490         int vshader;
1491         int pshader;
1492         D3DFOGMODE vfog;
1493         D3DFOGMODE tfog;
1494         unsigned int color[11];
1495     } test_data[] = {
1496         /* only pixel shader: */
1497         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1498         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1499         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1500         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1501         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1502         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1503         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1504         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1505         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1506         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1507         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1508         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1510         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1511         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1512
1513         /* vertex shader */
1514         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1515         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1516          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1517         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1518         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1519         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1520         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1521         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1522         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1523
1524         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader and pixel shader */
1532         /* The next 4 tests would read the fog coord output, but it isn't available.
1533          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1534          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1535          * These tests should be disabled if some other hardware behaves differently
1536          */
1537         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1538         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1539         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1540         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1541         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1542         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1543         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1544         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1545         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1546         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1547         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1548         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1549
1550         /* These use the Z coordinate with linear table fog */
1551         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1552         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1553         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1554         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1555         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1556         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1557         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1558         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1559         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1560         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1561         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1562         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1563
1564         /* Non-linear table fog without fog coord */
1565         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1566         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1567         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1568         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1569         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1570         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1571
1572 #if 0  /* FIXME: these fail on GeForce 8500 */
1573         /* foggy vertex shader */
1574         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1575         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1576          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1577         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1578         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1579          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1580         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1581         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1582          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1583         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1584         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1585          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1586 #endif
1587
1588         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1589          * all using the fixed fog-coord linear fog
1590          */
1591         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1592         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1593          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1594         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1595         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1596          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1597         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1598         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1599          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1600         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1601         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1602          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1603
1604         /* These use table fog. Here the shader-provided fog coordinate is
1605          * ignored and the z coordinate used instead
1606          */
1607         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1608         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1609         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1610         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1611         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1612         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1613         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1614         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1615         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1616     };
1617
1618     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1619     start.f=0.1f;
1620     end.f=0.9f;
1621
1622     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1623     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1624     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1625     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1626     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1627     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1628     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1629     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1630
1631     /* Setup initial states: No lighting, fog on, fog color */
1632     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1633     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1634     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1635     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1637     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1638     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1639     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1640
1641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1642     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1643     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1644     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1645
1646     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1647     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1648     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1650     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1651
1652     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1653     {
1654         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1655         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1656         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1657         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1658         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1659         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1660         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1661         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1662
1663         for(j=0; j < 11; j++)
1664         {
1665             /* Don't use the whole zrange to prevent rounding errors */
1666             quad[0].z = 0.001f + (float)j / 10.02f;
1667             quad[1].z = 0.001f + (float)j / 10.02f;
1668             quad[2].z = 0.001f + (float)j / 10.02f;
1669             quad[3].z = 0.001f + (float)j / 10.02f;
1670
1671             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1672             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1673
1674             hr = IDirect3DDevice9_BeginScene(device);
1675             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1676
1677             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1678             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679
1680             hr = IDirect3DDevice9_EndScene(device);
1681             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1682
1683             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1684             color = getPixelColor(device, 128, 240);
1685             ok(color_match(color, test_data[i].color[j], 13),
1686                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1687                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1688
1689             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1690         }
1691     }
1692
1693     /* reset states */
1694     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1695     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1696     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1697     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1698     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1699     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1700     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1701     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1702
1703     IDirect3DVertexShader9_Release(vertex_shader[1]);
1704     IDirect3DVertexShader9_Release(vertex_shader[2]);
1705     IDirect3DPixelShader9_Release(pixel_shader[1]);
1706     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1707 }
1708
1709 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1710     unsigned int i, x, y;
1711     HRESULT hr;
1712     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1713     D3DLOCKED_RECT locked_rect;
1714
1715     /* Generate the textures */
1716     for(i=0; i<2; i++)
1717     {
1718         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1719                                             D3DPOOL_MANAGED, &texture[i], NULL);
1720         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1721
1722         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1723         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1724         for (y = 0; y < 128; ++y)
1725         {
1726             if(i)
1727             { /* Set up black texture with 2x2 texel white spot in the middle */
1728                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1729                 for (x = 0; x < 128; ++x)
1730                 {
1731                     if(y>62 && y<66 && x>62 && x<66)
1732                         *ptr++ = 0xffffffff;
1733                     else
1734                         *ptr++ = 0xff000000;
1735                 }
1736             }
1737             else
1738             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1739                * (if multiplied with bumpenvmat)
1740               */
1741                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1742                 for (x = 0; x < 128; ++x)
1743                 {
1744                     if(abs(x-64)>abs(y-64))
1745                     {
1746                         if(x < 64)
1747                             *ptr++ = 0xc000;
1748                         else
1749                             *ptr++ = 0x4000;
1750                     }
1751                     else
1752                     {
1753                         if(y < 64)
1754                             *ptr++ = 0x0040;
1755                         else
1756                             *ptr++ = 0x00c0;
1757                     }
1758                 }
1759             }
1760         }
1761         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1762         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1763
1764         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1765         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1766
1767         /* Disable texture filtering */
1768         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1769         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1770         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1771         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1772
1773         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1775         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1776         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1777     }
1778 }
1779
1780 /* test the behavior of the texbem instruction
1781  * with normal 2D and projective 2D textures
1782  */
1783 static void texbem_test(IDirect3DDevice9 *device)
1784 {
1785     HRESULT hr;
1786     DWORD color;
1787     int i;
1788
1789     static const DWORD pixel_shader_code[] = {
1790         0xffff0101,                         /* ps_1_1*/
1791         0x00000042, 0xb00f0000,             /* tex t0*/
1792         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1793         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1794         0x0000ffff
1795     };
1796     static const DWORD double_texbem_code[] =  {
1797         0xffff0103,                                         /* ps_1_3           */
1798         0x00000042, 0xb00f0000,                             /* tex t0           */
1799         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1800         0x00000042, 0xb00f0002,                             /* tex t2           */
1801         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1802         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1803         0x0000ffff                                          /* end              */
1804     };
1805
1806
1807     static const float quad[][7] = {
1808         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1809         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1810         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1811         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1812     };
1813     static const float quad_proj[][9] = {
1814         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1815         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1816         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1817         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1818     };
1819
1820     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1821         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1822         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1823         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1824         D3DDECL_END()
1825     },{
1826         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1827         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1828         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1829         D3DDECL_END()
1830     } };
1831
1832     /* use asymmetric matrix to test loading */
1833     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1834
1835     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1836     IDirect3DPixelShader9       *pixel_shader       = NULL;
1837     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1838     D3DLOCKED_RECT locked_rect;
1839
1840     generate_bumpmap_textures(device);
1841
1842     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1846     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1847
1848     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1849     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1850
1851     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1852     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1853
1854     for(i=0; i<2; i++)
1855     {
1856         if(i)
1857         {
1858             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1859             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1860         }
1861
1862         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1863         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1864         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1865         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1866
1867         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1868         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1869         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1870         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1871
1872         hr = IDirect3DDevice9_BeginScene(device);
1873         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1874
1875         if(!i)
1876             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1877         else
1878             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1879         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1880
1881         hr = IDirect3DDevice9_EndScene(device);
1882         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1883
1884         color = getPixelColor(device, 320-32, 240);
1885         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1886         color = getPixelColor(device, 320+32, 240);
1887         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1888         color = getPixelColor(device, 320, 240-32);
1889         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1890         color = getPixelColor(device, 320, 240+32);
1891         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1892
1893         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1894         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1895
1896         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1897         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1898         IDirect3DPixelShader9_Release(pixel_shader);
1899
1900         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1901         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1902         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1903     }
1904
1905     /* clean up */
1906     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1907     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1908
1909     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1910     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1911
1912     for(i=0; i<2; i++)
1913     {
1914         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1915         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1916         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1917         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1918         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1919         IDirect3DTexture9_Release(texture);
1920     }
1921
1922     /* Test double texbem */
1923     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1924     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1925     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1926     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1927     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1928     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1929     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1930     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1931
1932     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1933     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1934     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1935     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1936
1937     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1938     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1939
1940     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1941     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1942     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1943     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1944     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1945     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1946
1947     {
1948         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1949 #define tex  0x00ff0000
1950 #define tex1 0x0000ff00
1951 #define origin 0x000000ff
1952         static const DWORD pixel_data[] = {
1953             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1954             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1955             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1956             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1957             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1958             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1959             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1960             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1961         };
1962 #undef tex1
1963 #undef tex2
1964 #undef origin
1965
1966         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1967         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1968         for(i = 0; i < 8; i++) {
1969             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1970         }
1971         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1972         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1973     }
1974
1975     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1976     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1977     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1978     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1979     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1980     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1981     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1983     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1984     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1985     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1986     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1987
1988     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
1989     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
1990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1991     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1992     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1993     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1994     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1995     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1996     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1997     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
1998
1999     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2000     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2001     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2002     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2003     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2004     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2005     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2006     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2007     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2008     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2009
2010     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2016     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2017     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2018     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2019     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2020     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2021     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2022     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2023     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2024     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2025     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2026
2027     hr = IDirect3DDevice9_BeginScene(device);
2028     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2029     if(SUCCEEDED(hr)) {
2030         static const float double_quad[] = {
2031             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2032              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2033             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2034              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2035         };
2036
2037         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2038         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2039         hr = IDirect3DDevice9_EndScene(device);
2040         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2041     }
2042     color = getPixelColor(device, 320, 240);
2043     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2044
2045     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2046     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2047     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2048     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2049     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2050     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2051     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2052     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2053     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2054     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2055
2056     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2057     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2058
2059     IDirect3DPixelShader9_Release(pixel_shader);
2060     IDirect3DTexture9_Release(texture);
2061     IDirect3DTexture9_Release(texture1);
2062     IDirect3DTexture9_Release(texture2);
2063 }
2064
2065 static void z_range_test(IDirect3DDevice9 *device)
2066 {
2067     const struct vertex quad[] =
2068     {
2069         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2070         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2071         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2072         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2073     };
2074     const struct vertex quad2[] =
2075     {
2076         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2077         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2078         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2079         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2080     };
2081
2082     const struct tvertex quad3[] =
2083     {
2084         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2085         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2086         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2087         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2088     };
2089     const struct tvertex quad4[] =
2090     {
2091         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2092         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2093         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2094         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2095     };
2096     HRESULT hr;
2097     DWORD color;
2098     IDirect3DVertexShader9 *shader;
2099     IDirect3DVertexDeclaration9 *decl;
2100     D3DCAPS9 caps;
2101     const DWORD shader_code[] = {
2102         0xfffe0101,                                     /* vs_1_1           */
2103         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2104         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2105         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2106         0x0000ffff                                      /* end              */
2107     };
2108     static const D3DVERTEXELEMENT9 decl_elements[] = {
2109         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2110         D3DDECL_END()
2111     };
2112     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2113      * then call Present. Then clear the color buffer to make sure it has some defined content
2114      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2115      * by the depth value.
2116      */
2117     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2118     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2119     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2120     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2121     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2122     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2123
2124     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2125     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2133     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2134
2135     hr = IDirect3DDevice9_BeginScene(device);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2137     if(hr == D3D_OK)
2138     {
2139         /* Test the untransformed vertex path */
2140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2141         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2142         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2143         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2145         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2146
2147         /* Test the transformed vertex path */
2148         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2149         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2150
2151         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2152         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2153         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2154         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2156         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2157
2158         hr = IDirect3DDevice9_EndScene(device);
2159         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2160     }
2161
2162     /* Do not test the exact corner pixels, but go pretty close to them */
2163
2164     /* Clipped because z > 1.0 */
2165     color = getPixelColor(device, 28, 238);
2166     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2167     color = getPixelColor(device, 28, 241);
2168     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2169
2170     /* Not clipped, > z buffer clear value(0.75) */
2171     color = getPixelColor(device, 31, 238);
2172     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2173     color = getPixelColor(device, 31, 241);
2174     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2175     color = getPixelColor(device, 100, 238);
2176     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2177     color = getPixelColor(device, 100, 241);
2178     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2179
2180     /* Not clipped, < z buffer clear value */
2181     color = getPixelColor(device, 104, 238);
2182     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2183     color = getPixelColor(device, 104, 241);
2184     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2185     color = getPixelColor(device, 318, 238);
2186     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2187     color = getPixelColor(device, 318, 241);
2188     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2189
2190     /* Clipped because z < 0.0 */
2191     color = getPixelColor(device, 321, 238);
2192     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2193     color = getPixelColor(device, 321, 241);
2194     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2195
2196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2197     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2198
2199     /* Test the shader path */
2200     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2201     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2202         skip("Vertex shaders not supported\n");
2203         goto out;
2204     }
2205     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2209
2210     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2211
2212     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2213     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2214     IDirect3DDevice9_SetVertexShader(device, shader);
2215     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2216
2217     hr = IDirect3DDevice9_BeginScene(device);
2218     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2219     if(hr == D3D_OK)
2220     {
2221         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2222         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2223         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2224         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2225         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2226         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2227         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2228         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2229         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2230         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2231
2232         hr = IDirect3DDevice9_EndScene(device);
2233         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2234     }
2235
2236     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2237     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2238     IDirect3DDevice9_SetVertexShader(device, NULL);
2239     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2240
2241     IDirect3DVertexDeclaration9_Release(decl);
2242     IDirect3DVertexShader9_Release(shader);
2243
2244     /* Z < 1.0 */
2245     color = getPixelColor(device, 28, 238);
2246     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2247
2248     /* 1.0 < z < 0.75 */
2249     color = getPixelColor(device, 31, 238);
2250     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2251     color = getPixelColor(device, 100, 238);
2252     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2253
2254     /* 0.75 < z < 0.0 */
2255     color = getPixelColor(device, 104, 238);
2256     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2257     color = getPixelColor(device, 318, 238);
2258     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2259
2260     /* 0.0 < z */
2261     color = getPixelColor(device, 321, 238);
2262     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2263
2264     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2265     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2266
2267     out:
2268     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2269     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2270     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2271     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2272     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2273     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2274 }
2275
2276 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2277 {
2278     D3DSURFACE_DESC desc;
2279     D3DLOCKED_RECT l;
2280     HRESULT hr;
2281     unsigned int x, y;
2282     DWORD *mem;
2283
2284     memset(&desc, 0, sizeof(desc));
2285     memset(&l, 0, sizeof(l));
2286     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2287     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2288     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2289     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2290     if(FAILED(hr)) return;
2291
2292     for(y = 0; y < desc.Height; y++)
2293     {
2294         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2295         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2296         {
2297             mem[x] = color;
2298         }
2299     }
2300     hr = IDirect3DSurface9_UnlockRect(surface);
2301     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2302 }
2303
2304 /* This tests a variety of possible StretchRect() situations */
2305 static void stretchrect_test(IDirect3DDevice9 *device)
2306 {
2307     HRESULT hr;
2308     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2309     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2310     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2311     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2312     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2313     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2314     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2315     IDirect3DSurface9 *orig_rt = NULL;
2316     IDirect3DSurface9 *backbuffer = NULL;
2317     DWORD color;
2318
2319     RECT src_rect64 = {0, 0, 64, 64};
2320     RECT src_rect64_flipy = {0, 64, 64, 0};
2321     RECT dst_rect64 = {0, 0, 64, 64};
2322     RECT dst_rect64_flipy = {0, 64, 64, 0};
2323
2324     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2325     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2326     if(!orig_rt) {
2327         goto out;
2328     }
2329
2330     /* Create our temporary surfaces in system memory */
2331     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2332     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2333     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2334     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2335
2336     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2337     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2339     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2340     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2341     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2342     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2343
2344     /* Create render target surfaces */
2345     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2346     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2347     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2348     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2349     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2350     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2352     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2353
2354     /* Create render target textures */
2355     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2356     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2358     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2360     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2361     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2362     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2363     if (tex_rt32) {
2364         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2365         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2366     }
2367     if (tex_rt64) {
2368         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2369         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2370     }
2371     if (tex_rt_dest64) {
2372         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2373         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2374     }
2375     if (tex_rt_dest64) {
2376         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2377         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2378     }
2379
2380     /* Create regular textures in D3DPOOL_DEFAULT */
2381     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2382     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2383     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2384     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2385     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2386     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2387     if (tex32) {
2388         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2389         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2390     }
2391     if (tex64) {
2392         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2393         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2394     }
2395     if (tex_dest64) {
2396         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2397         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2398     }
2399
2400     /*********************************************************************
2401      * Tests for when the source parameter is an offscreen plain surface *
2402      *********************************************************************/
2403
2404     /* Fill the offscreen 64x64 surface with green */
2405     if (surf_offscreen64)
2406         fill_surface(surf_offscreen64, 0xff00ff00);
2407
2408     /* offscreenplain ==> offscreenplain, same size */
2409     if(surf_offscreen64 && surf_offscreen_dest64) {
2410         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2411         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2412
2413         if (hr == D3D_OK) {
2414             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2415             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2416         }
2417
2418         /* Blit without scaling */
2419         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2420         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2421
2422         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2423         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2424         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2425
2426         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2427         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2428         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2429     }
2430
2431     /* offscreenplain ==> rendertarget texture, same size */
2432     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2433         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2434         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2435
2436         /* We can't lock rendertarget textures, so copy to our temp surface first */
2437         if (hr == D3D_OK) {
2438             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2439             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2440         }
2441
2442         if (hr == D3D_OK) {
2443             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2444             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2445         }
2446
2447         /* Blit without scaling */
2448         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2449         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450
2451         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2452         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2453         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2454
2455         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2456         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2457         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2458     }
2459
2460     /* offscreenplain ==> rendertarget surface, same size */
2461     if(surf_offscreen64 && surf_rt_dest64) {
2462         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2463         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2464
2465         if (hr == D3D_OK) {
2466             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2467             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2468         }
2469
2470         /* Blit without scaling */
2471         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2472         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2473
2474         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2475         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2476         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2477
2478         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2479         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2480         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481     }
2482
2483     /* offscreenplain ==> texture, same size (should fail) */
2484     if(surf_offscreen64 && surf_tex_dest64) {
2485         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2486         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2487     }
2488
2489     /* Fill the smaller offscreen surface with red */
2490     fill_surface(surf_offscreen32, 0xffff0000);
2491
2492     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2493     if(surf_offscreen32 && surf_offscreen64) {
2494         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2495         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2496     }
2497
2498     /* offscreenplain ==> rendertarget texture, scaling */
2499     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2500         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2501         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2502
2503         /* We can't lock rendertarget textures, so copy to our temp surface first */
2504         if (hr == D3D_OK) {
2505             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2506             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2507         }
2508
2509         if (hr == D3D_OK) {
2510             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2511             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2512         }
2513     }
2514
2515     /* offscreenplain ==> rendertarget surface, scaling */
2516     if(surf_offscreen32 && surf_rt_dest64) {
2517         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2518         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2519
2520         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2521         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2522     }
2523
2524     /* offscreenplain ==> texture, scaling (should fail) */
2525     if(surf_offscreen32 && surf_tex_dest64) {
2526         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2527         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2528     }
2529
2530     /************************************************************
2531      * Tests for when the source parameter is a regular texture *
2532      ************************************************************/
2533
2534     /* Fill the surface of the regular texture with blue */
2535     if (surf_tex64 && surf_temp64) {
2536         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2537         fill_surface(surf_temp64, 0xff0000ff);
2538         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2539         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2540     }
2541
2542     /* texture ==> offscreenplain, same size */
2543     if(surf_tex64 && surf_offscreen64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /* texture ==> rendertarget texture, same size */
2549     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2550         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2551         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2552
2553         /* We can't lock rendertarget textures, so copy to our temp surface first */
2554         if (hr == D3D_OK) {
2555             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2556             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2557         }
2558
2559         if (hr == D3D_OK) {
2560             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2561             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2562         }
2563
2564         /* Blit without scaling */
2565         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2566         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2567
2568         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2569         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2570         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571
2572         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2573         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2574         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2575     }
2576
2577     /* texture ==> rendertarget surface, same size */
2578     if(surf_tex64 && surf_rt_dest64) {
2579         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2580         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2581
2582         if (hr == D3D_OK) {
2583             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2584             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2585         }
2586
2587         /* Blit without scaling */
2588         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2589         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2590
2591         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2592         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2593         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2594
2595         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2596         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2597         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2598     }
2599
2600     /* texture ==> texture, same size (should fail) */
2601     if(surf_tex64 && surf_tex_dest64) {
2602         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2603         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2604     }
2605
2606     /* Fill the surface of the smaller regular texture with red */
2607     if (surf_tex32 && surf_temp32) {
2608         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2609         fill_surface(surf_temp32, 0xffff0000);
2610         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2611         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2612     }
2613
2614     /* texture ==> offscreenplain, scaling (should fail) */
2615     if(surf_tex32 && surf_offscreen64) {
2616         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2617         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2618     }
2619
2620     /* texture ==> rendertarget texture, scaling */
2621     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2622         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2623         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2624
2625         /* We can't lock rendertarget textures, so copy to our temp surface first */
2626         if (hr == D3D_OK) {
2627             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2628             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2629         }
2630
2631         if (hr == D3D_OK) {
2632             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2633             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2634         }
2635     }
2636
2637     /* texture ==> rendertarget surface, scaling */
2638     if(surf_tex32 && surf_rt_dest64) {
2639         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2640         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2641
2642         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2643         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2644     }
2645
2646     /* texture ==> texture, scaling (should fail) */
2647     if(surf_tex32 && surf_tex_dest64) {
2648         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2649         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2650     }
2651
2652     /*****************************************************************
2653      * Tests for when the source parameter is a rendertarget texture *
2654      *****************************************************************/
2655
2656     /* Fill the surface of the rendertarget texture with white */
2657     if (surf_tex_rt64 && surf_temp64) {
2658         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2659         fill_surface(surf_temp64, 0xffffffff);
2660         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2661         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2662     }
2663
2664     /* rendertarget texture ==> offscreenplain, same size */
2665     if(surf_tex_rt64 && surf_offscreen64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /* rendertarget texture ==> rendertarget texture, same size */
2671     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2672         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2673         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2674
2675         /* We can't lock rendertarget textures, so copy to our temp surface first */
2676         if (hr == D3D_OK) {
2677             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2678             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2679         }
2680
2681         if (hr == D3D_OK) {
2682             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2683             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2684         }
2685
2686         /* Blit without scaling */
2687         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2688         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2689
2690         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2691         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2692         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2693
2694         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2695         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2696         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2697     }
2698
2699     /* rendertarget texture ==> rendertarget surface, same size */
2700     if(surf_tex_rt64 && surf_rt_dest64) {
2701         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2702         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2703
2704         if (hr == D3D_OK) {
2705             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2706             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2707         }
2708
2709         /* Blit without scaling */
2710         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2711         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2712
2713         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2714         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2715         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2716
2717         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2718         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2719         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2720     }
2721
2722     /* rendertarget texture ==> texture, same size (should fail) */
2723     if(surf_tex_rt64 && surf_tex_dest64) {
2724         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2725         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2726     }
2727
2728     /* Fill the surface of the smaller rendertarget texture with red */
2729     if (surf_tex_rt32 && surf_temp32) {
2730         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2731         fill_surface(surf_temp32, 0xffff0000);
2732         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2733         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2734     }
2735
2736     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2737     if(surf_tex_rt32 && surf_offscreen64) {
2738         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2739         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2740     }
2741
2742     /* rendertarget texture ==> rendertarget texture, scaling */
2743     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2744         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2745         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2746
2747         /* We can't lock rendertarget textures, so copy to our temp surface first */
2748         if (hr == D3D_OK) {
2749             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2750             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2751         }
2752
2753         if (hr == D3D_OK) {
2754             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2755             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2756         }
2757     }
2758
2759     /* rendertarget texture ==> rendertarget surface, scaling */
2760     if(surf_tex_rt32 && surf_rt_dest64) {
2761         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2762         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2763
2764         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2765         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2766     }
2767
2768     /* rendertarget texture ==> texture, scaling (should fail) */
2769     if(surf_tex_rt32 && surf_tex_dest64) {
2770         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2771         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2772     }
2773
2774     /*****************************************************************
2775      * Tests for when the source parameter is a rendertarget surface *
2776      *****************************************************************/
2777
2778     /* Fill the surface of the rendertarget surface with black */
2779     if (surf_rt64)
2780         fill_surface(surf_rt64, 0xff000000);
2781
2782     /* rendertarget texture ==> offscreenplain, same size */
2783     if(surf_rt64 && surf_offscreen64) {
2784         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2785         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2786     }
2787
2788     /* rendertarget surface ==> rendertarget texture, same size */
2789     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2790         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2791         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2792
2793         /* We can't lock rendertarget textures, so copy to our temp surface first */
2794         if (hr == D3D_OK) {
2795             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2796             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2797         }
2798
2799         if (hr == D3D_OK) {
2800             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2801             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2802         }
2803
2804         /* Blit without scaling */
2805         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2806         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2807
2808         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2809         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2810         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2811
2812         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2813         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2814         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2815     }
2816
2817     /* rendertarget surface ==> rendertarget surface, same size */
2818     if(surf_rt64 && surf_rt_dest64) {
2819         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2820         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2821
2822         if (hr == D3D_OK) {
2823             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2824             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2825         }
2826
2827         /* Blit without scaling */
2828         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2829         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2830
2831         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2832         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2833         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2834
2835         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2836         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2837         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2838     }
2839
2840     /* rendertarget surface ==> texture, same size (should fail) */
2841     if(surf_rt64 && surf_tex_dest64) {
2842         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2843         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2844     }
2845
2846     /* Fill the surface of the smaller rendertarget texture with red */
2847     if (surf_rt32)
2848         fill_surface(surf_rt32, 0xffff0000);
2849
2850     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2851     if(surf_rt32 && surf_offscreen64) {
2852         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2853         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2854     }
2855
2856     /* rendertarget surface ==> rendertarget texture, scaling */
2857     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2858         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2859         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2860
2861         /* We can't lock rendertarget textures, so copy to our temp surface first */
2862         if (hr == D3D_OK) {
2863             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2864             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2865         }
2866
2867         if (hr == D3D_OK) {
2868             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2869             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2870         }
2871     }
2872
2873     /* rendertarget surface ==> rendertarget surface, scaling */
2874     if(surf_rt32 && surf_rt_dest64) {
2875         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2876         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2877
2878         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2879         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2880     }
2881
2882     /* rendertarget surface ==> texture, scaling (should fail) */
2883     if(surf_rt32 && surf_tex_dest64) {
2884         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2885         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2886     }
2887
2888     /* backbuffer ==> surface tests (no scaling) */
2889     if(backbuffer && surf_tex_rt_dest640_480)
2890     {
2891         RECT src_rect = {0, 0, 640, 480};
2892         RECT src_rect_flipy = {0, 480, 640, 0};
2893         RECT dst_rect = {0, 0, 640, 480};
2894         RECT dst_rect_flipy = {0, 480, 640, 0};
2895
2896         /* Blit with NULL rectangles */
2897         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2898         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2899
2900         /* Blit without scaling */
2901         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2902         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2903
2904         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2905         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2906         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2907
2908         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2909         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2910         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2911     }
2912
2913     /* TODO: Test format conversions */
2914
2915
2916 out:
2917     /* Clean up */
2918     if (backbuffer)
2919         IDirect3DSurface9_Release(backbuffer);
2920     if (surf_rt32)
2921         IDirect3DSurface9_Release(surf_rt32);
2922     if (surf_rt64)
2923         IDirect3DSurface9_Release(surf_rt64);
2924     if (surf_rt_dest64)
2925         IDirect3DSurface9_Release(surf_rt_dest64);
2926     if (surf_temp32)
2927         IDirect3DSurface9_Release(surf_temp32);
2928     if (surf_temp64)
2929         IDirect3DSurface9_Release(surf_temp64);
2930     if (surf_offscreen32)
2931         IDirect3DSurface9_Release(surf_offscreen32);
2932     if (surf_offscreen64)
2933         IDirect3DSurface9_Release(surf_offscreen64);
2934     if (surf_offscreen_dest64)
2935         IDirect3DSurface9_Release(surf_offscreen_dest64);
2936
2937     if (tex_rt32) {
2938         if (surf_tex_rt32)
2939             IDirect3DSurface9_Release(surf_tex_rt32);
2940         IDirect3DTexture9_Release(tex_rt32);
2941     }
2942     if (tex_rt64) {
2943         if (surf_tex_rt64)
2944             IDirect3DSurface9_Release(surf_tex_rt64);
2945         IDirect3DTexture9_Release(tex_rt64);
2946     }
2947     if (tex_rt_dest64) {
2948         if (surf_tex_rt_dest64)
2949             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2950         IDirect3DTexture9_Release(tex_rt_dest64);
2951     }
2952     if (tex_rt_dest640_480) {
2953         if (surf_tex_rt_dest640_480)
2954             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2955         IDirect3DTexture9_Release(tex_rt_dest640_480);
2956     }
2957     if (tex32) {
2958         if (surf_tex32)
2959             IDirect3DSurface9_Release(surf_tex32);
2960         IDirect3DTexture9_Release(tex32);
2961     }
2962     if (tex64) {
2963         if (surf_tex64)
2964             IDirect3DSurface9_Release(surf_tex64);
2965         IDirect3DTexture9_Release(tex64);
2966     }
2967     if (tex_dest64) {
2968         if (surf_tex_dest64)
2969             IDirect3DSurface9_Release(surf_tex_dest64);
2970         IDirect3DTexture9_Release(tex_dest64);
2971     }
2972
2973     if (orig_rt) {
2974         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2975         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2976         IDirect3DSurface9_Release(orig_rt);
2977     }
2978 }
2979
2980 static void maxmip_test(IDirect3DDevice9 *device)
2981 {
2982     IDirect3DTexture9 *texture = NULL;
2983     IDirect3DSurface9 *surface = NULL;
2984     HRESULT hr;
2985     DWORD color;
2986     static const struct
2987     {
2988         struct
2989         {
2990             float x, y, z;
2991             float s, t;
2992         }
2993         v[4];
2994     }
2995     quads[] =
2996     {
2997         {{
2998             {-1.0, -1.0,  0.0,  0.0,  0.0},
2999             {-1.0,  0.0,  0.0,  0.0,  1.0},
3000             { 0.0, -1.0,  0.0,  1.0,  0.0},
3001             { 0.0,  0.0,  0.0,  1.0,  1.0},
3002         }},
3003         {{
3004             { 0.0, -1.0,  0.0,  0.0,  0.0},
3005             { 0.0,  0.0,  0.0,  0.0,  1.0},
3006             { 1.0, -1.0,  0.0,  1.0,  0.0},
3007             { 1.0,  0.0,  0.0,  1.0,  1.0},
3008         }},
3009         {{
3010             { 0.0,  0.0,  0.0,  0.0,  0.0},
3011             { 0.0,  1.0,  0.0,  0.0,  1.0},
3012             { 1.0,  0.0,  0.0,  1.0,  0.0},
3013             { 1.0,  1.0,  0.0,  1.0,  1.0},
3014         }},
3015         {{
3016             {-1.0,  0.0,  0.0,  0.0,  0.0},
3017             {-1.0,  1.0,  0.0,  0.0,  1.0},
3018             { 0.0,  0.0,  0.0,  1.0,  0.0},
3019             { 0.0,  1.0,  0.0,  1.0,  1.0},
3020         }},
3021     };
3022
3023     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3024                                         &texture, NULL);
3025     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3026     if(!texture)
3027     {
3028         skip("Failed to create test texture\n");
3029         return;
3030     }
3031
3032     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3033     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3034     fill_surface(surface, 0xffff0000);
3035     IDirect3DSurface9_Release(surface);
3036     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3037     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3038     fill_surface(surface, 0xff00ff00);
3039     IDirect3DSurface9_Release(surface);
3040     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3041     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3042     fill_surface(surface, 0xff0000ff);
3043     IDirect3DSurface9_Release(surface);
3044
3045     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3046     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3048     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3049
3050     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3051     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3052
3053     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3054     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3055
3056     hr = IDirect3DDevice9_BeginScene(device);
3057     if(SUCCEEDED(hr))
3058     {
3059         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3060         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3061         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3062         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3063
3064         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3065         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3066         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3067         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3068
3069         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3070         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3071         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3072         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3073
3074         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3075         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3076         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3077         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3078         hr = IDirect3DDevice9_EndScene(device);
3079         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3080     }
3081
3082     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3083     color = getPixelColor(device, 160, 360);
3084     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3085     color = getPixelColor(device, 480, 360);
3086     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3087     color = getPixelColor(device, 480, 120);
3088     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3089     color = getPixelColor(device, 160, 120);
3090     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3091     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3092     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3093
3094     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3095     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3096
3097     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3098     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3099
3100     hr = IDirect3DDevice9_BeginScene(device);
3101     if(SUCCEEDED(hr))
3102     {
3103         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3104         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3105         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3106         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3107
3108         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3109         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3110         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3111         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3112
3113         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3114         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3115         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3116         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3117
3118         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3119         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3120         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3121         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3122         hr = IDirect3DDevice9_EndScene(device);
3123         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3124     }
3125
3126     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3127      * level 3 (> levels in texture) samples from the highest level in the
3128      * texture (level 2). */
3129     color = getPixelColor(device, 160, 360);
3130     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3131     color = getPixelColor(device, 480, 360);
3132     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3133     color = getPixelColor(device, 480, 120);
3134     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3135     color = getPixelColor(device, 160, 120);
3136     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3137     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3138     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3139
3140     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3141     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3142
3143     hr = IDirect3DDevice9_BeginScene(device);
3144     if(SUCCEEDED(hr))
3145     {
3146         DWORD ret;
3147
3148         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3149         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3150         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3151         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3152         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3153         ret = IDirect3DTexture9_SetLOD(texture, 1);
3154         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3155         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3156         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3157
3158         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3159         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3160         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3161         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3162         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3163         ret = IDirect3DTexture9_SetLOD(texture, 2);
3164         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3165         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3166         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3167
3168         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3169         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3170         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3171         ret = IDirect3DTexture9_SetLOD(texture, 1);
3172         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3173         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3174         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3175
3176         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3177         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3178         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3179         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3180         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3181         ret = IDirect3DTexture9_SetLOD(texture, 1);
3182         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3183         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3184         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3185         hr = IDirect3DDevice9_EndScene(device);
3186     }
3187
3188     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3189      * level 3 (> levels in texture) samples from the highest level in the
3190      * texture (level 2). */
3191     color = getPixelColor(device, 160, 360);
3192     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3193     color = getPixelColor(device, 480, 360);
3194     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3195     color = getPixelColor(device, 480, 120);
3196     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3197     color = getPixelColor(device, 160, 120);
3198     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3199
3200     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3201     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3202
3203     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3204     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3205     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3206     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3207     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3208     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3209     IDirect3DTexture9_Release(texture);
3210 }
3211
3212 static void release_buffer_test(IDirect3DDevice9 *device)
3213 {
3214     IDirect3DVertexBuffer9 *vb = NULL;
3215     IDirect3DIndexBuffer9 *ib = NULL;
3216     HRESULT hr;
3217     BYTE *data;
3218     LONG ref;
3219
3220     static const struct vertex quad[] = {
3221         {-1.0,      -1.0,       0.1,        0xffff0000},
3222         {-1.0,       1.0,       0.1,        0xffff0000},
3223         { 1.0,       1.0,       0.1,        0xffff0000},
3224
3225         {-1.0,      -1.0,       0.1,        0xff00ff00},
3226         {-1.0,       1.0,       0.1,        0xff00ff00},
3227         { 1.0,       1.0,       0.1,        0xff00ff00}
3228     };
3229     short indices[] = {3, 4, 5};
3230
3231     /* Index and vertex buffers should always be creatable */
3232     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3233                                               D3DPOOL_MANAGED, &vb, NULL);
3234     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3235     if(!vb) {
3236         skip("Failed to create a vertex buffer\n");
3237         return;
3238     }
3239     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3240     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3241     if(!ib) {
3242         skip("Failed to create an index buffer\n");
3243         return;
3244     }
3245
3246     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3247     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3248     memcpy(data, quad, sizeof(quad));
3249     hr = IDirect3DVertexBuffer9_Unlock(vb);
3250     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3251
3252     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3253     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3254     memcpy(data, indices, sizeof(indices));
3255     hr = IDirect3DIndexBuffer9_Unlock(ib);
3256     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3257
3258     hr = IDirect3DDevice9_SetIndices(device, ib);
3259     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3260     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3261     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3262     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3263     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3264
3265     /* Now destroy the bound index buffer and draw again */
3266     ref = IDirect3DIndexBuffer9_Release(ib);
3267     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3268
3269     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3270     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3271
3272     hr = IDirect3DDevice9_BeginScene(device);
3273     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3274     if(SUCCEEDED(hr))
3275     {
3276         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3277          * making assumptions about the indices or vertices
3278          */
3279         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3280         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3281         hr = IDirect3DDevice9_EndScene(device);
3282         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3283     }
3284
3285     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3286     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3287
3288     hr = IDirect3DDevice9_SetIndices(device, NULL);
3289     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3290     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3291     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3292
3293     /* Index buffer was already destroyed as part of the test */
3294     IDirect3DVertexBuffer9_Release(vb);
3295 }
3296
3297 static void float_texture_test(IDirect3DDevice9 *device)
3298 {
3299     IDirect3D9 *d3d = NULL;
3300     HRESULT hr;
3301     IDirect3DTexture9 *texture = NULL;
3302     D3DLOCKED_RECT lr;
3303     float *data;
3304     DWORD color;
3305     float quad[] = {
3306         -1.0,      -1.0,       0.1,     0.0,    0.0,
3307         -1.0,       1.0,       0.1,     0.0,    1.0,
3308          1.0,      -1.0,       0.1,     1.0,    0.0,
3309          1.0,       1.0,       0.1,     1.0,    1.0,
3310     };
3311
3312     memset(&lr, 0, sizeof(lr));
3313     IDirect3DDevice9_GetDirect3D(device, &d3d);
3314     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3315                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3316         skip("D3DFMT_R32F textures not supported\n");
3317         goto out;
3318     }
3319
3320     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3321                                         D3DPOOL_MANAGED, &texture, NULL);
3322     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3323     if(!texture) {
3324         skip("Failed to create R32F texture\n");
3325         goto out;
3326     }
3327
3328     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3329     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3330     data = lr.pBits;
3331     *data = 0.0;
3332     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3333     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3334
3335     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3336     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3337
3338     hr = IDirect3DDevice9_BeginScene(device);
3339     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3340     if(SUCCEEDED(hr))
3341     {
3342         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3343         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3344
3345         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3346         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3347
3348         hr = IDirect3DDevice9_EndScene(device);
3349         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3350     }
3351     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3352     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3353
3354     color = getPixelColor(device, 240, 320);
3355     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3356
3357     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3358     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3359
3360 out:
3361     if(texture) IDirect3DTexture9_Release(texture);
3362     IDirect3D9_Release(d3d);
3363 }
3364
3365 static void g16r16_texture_test(IDirect3DDevice9 *device)
3366 {
3367     IDirect3D9 *d3d = NULL;
3368     HRESULT hr;
3369     IDirect3DTexture9 *texture = NULL;
3370     D3DLOCKED_RECT lr;
3371     DWORD *data;
3372     DWORD color;
3373     float quad[] = {
3374        -1.0,      -1.0,       0.1,     0.0,    0.0,
3375        -1.0,       1.0,       0.1,     0.0,    1.0,
3376         1.0,      -1.0,       0.1,     1.0,    0.0,
3377         1.0,       1.0,       0.1,     1.0,    1.0,
3378     };
3379
3380     memset(&lr, 0, sizeof(lr));
3381     IDirect3DDevice9_GetDirect3D(device, &d3d);
3382     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3383        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3384            skip("D3DFMT_G16R16 textures not supported\n");
3385            goto out;
3386     }
3387
3388     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3389                                         D3DPOOL_MANAGED, &texture, NULL);
3390     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3391     if(!texture) {
3392         skip("Failed to create D3DFMT_G16R16 texture\n");
3393         goto out;
3394     }
3395
3396     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3397     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3398     data = lr.pBits;
3399     *data = 0x0f00f000;
3400     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3401     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3402
3403     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3404     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3405
3406     hr = IDirect3DDevice9_BeginScene(device);
3407     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3408     if(SUCCEEDED(hr))
3409     {
3410         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3411         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3412
3413         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3414         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3415
3416         hr = IDirect3DDevice9_EndScene(device);
3417         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3418     }
3419     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3421
3422     color = getPixelColor(device, 240, 320);
3423     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3424        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3425
3426     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3427     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3428
3429 out:
3430     if(texture) IDirect3DTexture9_Release(texture);
3431     IDirect3D9_Release(d3d);
3432 }
3433
3434 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3435 {
3436     HRESULT hr;
3437     IDirect3D9 *d3d;
3438     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3439     D3DCAPS9 caps;
3440     IDirect3DTexture9 *texture = NULL;
3441     IDirect3DVolumeTexture9 *volume = NULL;
3442     unsigned int x, y, z;
3443     D3DLOCKED_RECT lr;
3444     D3DLOCKED_BOX lb;
3445     DWORD color;
3446     UINT w, h;
3447     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3448     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3449                            0.0, 1.0, 0.0, 0.0,
3450                            0.0, 0.0, 1.0, 0.0,
3451                            0.0, 0.0, 0.0, 1.0};
3452     static const D3DVERTEXELEMENT9 decl_elements[] = {
3453         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3454         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3455         D3DDECL_END()
3456     };
3457     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3458         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3459         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3460         D3DDECL_END()
3461     };
3462     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3463         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3464         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3465         D3DDECL_END()
3466     };
3467     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3468                                                  0x00, 0xff, 0x00, 0x00,
3469                                                  0x00, 0x00, 0x00, 0x00,
3470                                                  0x00, 0x00, 0x00, 0x00};
3471
3472     memset(&lr, 0, sizeof(lr));
3473     memset(&lb, 0, sizeof(lb));
3474     IDirect3DDevice9_GetDirect3D(device, &d3d);
3475     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3476                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3477         fmt = D3DFMT_A16B16G16R16;
3478     }
3479     IDirect3D9_Release(d3d);
3480
3481     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3482     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3483     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3484     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3485     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3486     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3487     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3488     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3489     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3490     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3491     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3492     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3493     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3494     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3495     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3496     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3497     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3498     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3499     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3500     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3501     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3502     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3503     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3504     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3505
3506     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3507     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3508     w = min(1024, caps.MaxTextureWidth);
3509     h = min(1024, caps.MaxTextureHeight);
3510     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3511                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3512     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3513     if(!texture) {
3514         skip("Failed to create the test texture\n");
3515         return;
3516     }
3517
3518     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3519      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3520      * 1.0 in red and green for the x and y coords
3521      */
3522     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3523     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3524     for(y = 0; y < h; y++) {
3525         for(x = 0; x < w; x++) {
3526             double r_f = (double) y / (double) h;
3527             double g_f = (double) x / (double) w;
3528             if(fmt == D3DFMT_A16B16G16R16) {
3529                 unsigned short r, g;
3530                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3531                 r = (unsigned short) (r_f * 65536.0);
3532                 g = (unsigned short) (g_f * 65536.0);
3533                 dst[0] = r;
3534                 dst[1] = g;
3535                 dst[2] = 0;
3536                 dst[3] = 65535;
3537             } else {
3538                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3539                 unsigned char r = (unsigned char) (r_f * 255.0);
3540                 unsigned char g = (unsigned char) (g_f * 255.0);
3541                 dst[0] = 0;
3542                 dst[1] = g;
3543                 dst[2] = r;
3544                 dst[3] = 255;
3545             }
3546         }
3547     }
3548     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3549     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3550     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3551     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3552
3553     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3554     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3555     hr = IDirect3DDevice9_BeginScene(device);
3556     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3557     if(SUCCEEDED(hr))
3558     {
3559         float quad1[] = {
3560             -1.0,      -1.0,       0.1,     1.0,    1.0,
3561             -1.0,       0.0,       0.1,     1.0,    1.0,
3562              0.0,      -1.0,       0.1,     1.0,    1.0,
3563              0.0,       0.0,       0.1,     1.0,    1.0,
3564         };
3565         float quad2[] = {
3566             -1.0,       0.0,       0.1,     1.0,    1.0,
3567             -1.0,       1.0,       0.1,     1.0,    1.0,
3568              0.0,       0.0,       0.1,     1.0,    1.0,
3569              0.0,       1.0,       0.1,     1.0,    1.0,
3570         };
3571         float quad3[] = {
3572              0.0,       0.0,       0.1,     0.5,    0.5,
3573              0.0,       1.0,       0.1,     0.5,    0.5,
3574              1.0,       0.0,       0.1,     0.5,    0.5,
3575              1.0,       1.0,       0.1,     0.5,    0.5,
3576         };
3577         float quad4[] = {
3578              320,       480,       0.1,     1.0,    0.0,    1.0,
3579              320,       240,       0.1,     1.0,    0.0,    1.0,
3580              640,       480,       0.1,     1.0,    0.0,    1.0,
3581              640,       240,       0.1,     1.0,    0.0,    1.0,
3582         };
3583         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3584                           0.0, 0.0, 0.0, 0.0,
3585                           0.0, 0.0, 0.0, 0.0,
3586                           0.0, 0.0, 0.0, 0.0};
3587
3588         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3589         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3590         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3591         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3592         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3593
3594         /* What happens with transforms enabled? */
3595         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3596         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3597         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3598         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3599
3600         /* What happens if 4 coords are used, but only 2 given ?*/
3601         mat[8] = 1.0;
3602         mat[13] = 1.0;
3603         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3604         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3605         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3606         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3607         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3608         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3609
3610         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3611          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3612          * due to the coords in the vertices. (turns out red, indeed)
3613          */
3614         memset(mat, 0, sizeof(mat));
3615         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3616         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3617         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3618         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3619         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3620         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3621         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3622         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3623
3624         hr = IDirect3DDevice9_EndScene(device);
3625         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3626     }
3627     color = getPixelColor(device, 160, 360);
3628     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3629     color = getPixelColor(device, 160, 120);
3630     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3631     color = getPixelColor(device, 480, 120);
3632     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3633     color = getPixelColor(device, 480, 360);
3634     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3635     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3636     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3637
3638     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3639     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3640
3641     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3642     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3643     hr = IDirect3DDevice9_BeginScene(device);
3644     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3645     if(SUCCEEDED(hr))
3646     {
3647         float quad1[] = {
3648             -1.0,      -1.0,       0.1,     0.8,    0.2,
3649             -1.0,       0.0,       0.1,     0.8,    0.2,
3650              0.0,      -1.0,       0.1,     0.8,    0.2,
3651              0.0,       0.0,       0.1,     0.8,    0.2,
3652         };
3653         float quad2[] = {
3654             -1.0,       0.0,       0.1,     0.5,    1.0,
3655             -1.0,       1.0,       0.1,     0.5,    1.0,
3656              0.0,       0.0,       0.1,     0.5,    1.0,
3657              0.0,       1.0,       0.1,     0.5,    1.0,
3658         };
3659         float quad3[] = {
3660              0.0,       0.0,       0.1,     0.5,    1.0,
3661              0.0,       1.0,       0.1,     0.5,    1.0,
3662              1.0,       0.0,       0.1,     0.5,    1.0,
3663              1.0,       1.0,       0.1,     0.5,    1.0,
3664         };
3665         float quad4[] = {
3666              0.0,      -1.0,       0.1,     0.8,    0.2,
3667              0.0,       0.0,       0.1,     0.8,    0.2,
3668              1.0,      -1.0,       0.1,     0.8,    0.2,
3669              1.0,       0.0,       0.1,     0.8,    0.2,
3670         };
3671         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3672                           0.0, 0.0, 0.0, 0.0,
3673                           0.0, 1.0, 0.0, 0.0,
3674                           0.0, 0.0, 0.0, 0.0};
3675
3676         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3677          */
3678         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3679         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3680         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3681         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3682
3683         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3684         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3685
3686         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3687          * it behaves like COUNT2 because normal textures require 2 coords
3688          */
3689         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3690         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3691         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3692         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3693
3694         /* Just to be sure, the same as quad2 above */
3695         memset(mat, 0, sizeof(mat));
3696         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3697         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3698         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3699         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3700         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3701         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3702
3703         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3704          * used? And what happens to the first?
3705          */
3706         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3707         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3708         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3709         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3710
3711         hr = IDirect3DDevice9_EndScene(device);
3712         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3713     }
3714     color = getPixelColor(device, 160, 360);
3715     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3716     color = getPixelColor(device, 160, 120);
3717     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3718     color = getPixelColor(device, 480, 120);
3719     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3720        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3721     color = getPixelColor(device, 480, 360);
3722     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3723        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3724     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3725     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3726
3727     IDirect3DTexture9_Release(texture);
3728
3729     /* Test projected textures, without any fancy matrices */
3730     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3731     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3732     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3733     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3734     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3735     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3736     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3737     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3738
3739     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3740     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3741     for(x = 0; x < 4; x++) {
3742         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3743     }
3744     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3745     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3746     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3747     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3748
3749     hr = IDirect3DDevice9_BeginScene(device);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3751     if(SUCCEEDED(hr))
3752     {
3753         const float proj_quads[] = {
3754            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3755             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3756            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3757             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3758            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3759             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3760            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3761             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3762         };
3763
3764         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3765         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3766         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3767         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3768
3769         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3770         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3771         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3772         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3773
3774         hr = IDirect3DDevice9_EndScene(device);
3775         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3776     }
3777
3778     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3779     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3780     IDirect3DTexture9_Release(texture);
3781
3782     color = getPixelColor(device, 158, 118);
3783     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3784     color = getPixelColor(device, 162, 118);
3785     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3786     color = getPixelColor(device, 158, 122);
3787     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3788     color = getPixelColor(device, 162, 122);
3789     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3790
3791     color = getPixelColor(device, 158, 178);
3792     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3793     color = getPixelColor(device, 162, 178);
3794     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3795     color = getPixelColor(device, 158, 182);
3796     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3797     color = getPixelColor(device, 162, 182);
3798     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3799
3800     color = getPixelColor(device, 318, 118);
3801     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3802     color = getPixelColor(device, 322, 118);
3803     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3804     color = getPixelColor(device, 318, 122);
3805     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3806     color = getPixelColor(device, 322, 122);
3807     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3808
3809     color = getPixelColor(device, 318, 178);
3810     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3811     color = getPixelColor(device, 322, 178);
3812     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3813     color = getPixelColor(device, 318, 182);
3814     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3815     color = getPixelColor(device, 322, 182);
3816     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3817
3818     color = getPixelColor(device, 238, 298);
3819     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3820     color = getPixelColor(device, 242, 298);
3821     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3822     color = getPixelColor(device, 238, 302);
3823     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3824     color = getPixelColor(device, 242, 302);
3825     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3826
3827     color = getPixelColor(device, 238, 388);
3828     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3829     color = getPixelColor(device, 242, 388);
3830     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3831     color = getPixelColor(device, 238, 392);
3832     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3833     color = getPixelColor(device, 242, 392);
3834     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3835
3836     color = getPixelColor(device, 478, 298);
3837     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3838     color = getPixelColor(device, 482, 298);
3839     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3840     color = getPixelColor(device, 478, 302);
3841     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3842     color = getPixelColor(device, 482, 302);
3843     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3844
3845     color = getPixelColor(device, 478, 388);
3846     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3847     color = getPixelColor(device, 482, 388);
3848     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3849     color = getPixelColor(device, 478, 392);
3850     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3851     color = getPixelColor(device, 482, 392);
3852     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3853
3854     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3855     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3856
3857     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3858     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3859     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3860      * Thus watch out if sampling from texels between 0 and 1.
3861      */
3862     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3863     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3864        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3865     if(!volume) {
3866         skip("Failed to create a volume texture\n");
3867         goto out;
3868     }
3869
3870     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3871     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3872     for(z = 0; z < 32; z++) {
3873         for(y = 0; y < 32; y++) {
3874             for(x = 0; x < 32; x++) {
3875                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3876                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3877                 float r_f = (float) x / 31.0;
3878                 float g_f = (float) y / 31.0;
3879                 float b_f = (float) z / 31.0;
3880
3881                 if(fmt == D3DFMT_A16B16G16R16) {
3882                     unsigned short *mem_s = mem;
3883                     mem_s[0]  = r_f * 65535.0;
3884                     mem_s[1]  = g_f * 65535.0;
3885                     mem_s[2]  = b_f * 65535.0;
3886                     mem_s[3]  = 65535;
3887                 } else {
3888                     unsigned char *mem_c = mem;
3889                     mem_c[0]  = b_f * 255.0;
3890                     mem_c[1]  = g_f * 255.0;
3891                     mem_c[2]  = r_f * 255.0;
3892                     mem_c[3]  = 255;
3893                 }
3894             }
3895         }
3896     }
3897     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3898     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3899
3900     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3901     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3902
3903     hr = IDirect3DDevice9_BeginScene(device);
3904     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3905     if(SUCCEEDED(hr))
3906     {
3907         float quad1[] = {
3908             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3909             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3910              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3911              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3912         };
3913         float quad2[] = {
3914             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3915             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3916              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3917              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3918         };
3919         float quad3[] = {
3920              0.0,       0.0,       0.1,     0.0,    0.0,
3921              0.0,       1.0,       0.1,     0.0,    0.0,
3922              1.0,       0.0,       0.1,     0.0,    0.0,
3923              1.0,       1.0,       0.1,     0.0,    0.0
3924         };
3925         float quad4[] = {
3926              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3927              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3928              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3929              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3930         };
3931         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3932                          0.0, 0.0, 1.0, 0.0,
3933                          0.0, 1.0, 0.0, 0.0,
3934                          0.0, 0.0, 0.0, 1.0};
3935         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3936         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3937
3938         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3939          * values
3940          */
3941         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3942         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3943         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3944         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3945         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3946         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3947
3948         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3949          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3950          * otherwise the w will be missing(blue).
3951          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3952          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3953          */
3954         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3956         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3957         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3958
3959         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3960         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3961         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3962         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3963         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3964         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3965         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3966         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3967         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3968
3969         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3970          * disable. ATI extends it up to the amount of values needed for the volume texture
3971          */
3972         memset(mat, 0, sizeof(mat));
3973         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3974         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3975         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3976         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3977         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3978         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3979         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3980         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3981
3982         hr = IDirect3DDevice9_EndScene(device);
3983         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3984     }
3985
3986     color = getPixelColor(device, 160, 360);
3987     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3988     color = getPixelColor(device, 160, 120);
3989     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3990        "quad 2 has color %08x, expected 0x00ffff00\n", color);
3991     color = getPixelColor(device, 480, 120);
3992     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3993     color = getPixelColor(device, 480, 360);
3994     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3995
3996     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3997     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3998
3999     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4000     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4001     hr = IDirect3DDevice9_BeginScene(device);
4002     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4003     if(SUCCEEDED(hr))
4004     {
4005         float quad1[] = {
4006             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4007             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4008              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4009              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4010         };
4011         float quad2[] = {
4012             -1.0,       0.0,       0.1,
4013             -1.0,       1.0,       0.1,
4014              0.0,       0.0,       0.1,
4015              0.0,       1.0,       0.1,
4016         };
4017         float quad3[] = {
4018              0.0,       0.0,       0.1,     1.0,
4019              0.0,       1.0,       0.1,     1.0,
4020              1.0,       0.0,       0.1,     1.0,
4021              1.0,       1.0,       0.1,     1.0
4022         };
4023         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4024                            0.0, 0.0, 0.0, 0.0,
4025                            0.0, 0.0, 0.0, 0.0,
4026                            0.0, 1.0, 0.0, 0.0};
4027         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4028                            1.0, 0.0, 0.0, 0.0,
4029                            0.0, 1.0, 0.0, 0.0,
4030                            0.0, 0.0, 1.0, 0.0};
4031         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4032         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4033
4034         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4035          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4036          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4037          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4038          * 4th *input* coordinate.
4039          */
4040         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4041         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4042         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4043         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4044         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4045         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4046
4047         /* None passed */
4048         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4049         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4050         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4051         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4052         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4053         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4054
4055         /* 4 used, 1 passed */
4056         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4057         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4058         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4059         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4060         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4061         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4062
4063         hr = IDirect3DDevice9_EndScene(device);
4064         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4065     }
4066     color = getPixelColor(device, 160, 360);
4067     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4068     color = getPixelColor(device, 160, 120);
4069     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4070     color = getPixelColor(device, 480, 120);
4071     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4072     /* Quad4: unused */
4073
4074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4075     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4076
4077     IDirect3DVolumeTexture9_Release(volume);
4078
4079     out:
4080     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4081     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4082     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4083     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4084     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4085     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4086     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4087     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4088     IDirect3DVertexDeclaration9_Release(decl);
4089     IDirect3DVertexDeclaration9_Release(decl2);
4090     IDirect3DVertexDeclaration9_Release(decl3);
4091 }
4092
4093 static void texdepth_test(IDirect3DDevice9 *device)
4094 {
4095     IDirect3DPixelShader9 *shader;
4096     HRESULT hr;
4097     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4098     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4099     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4100     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4101     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4102     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4103     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4104     DWORD shader_code[] = {
4105         0xffff0104,                                                                 /* ps_1_4               */
4106         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4107         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4108         0x0000fffd,                                                                 /* phase                */
4109         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4110         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4111         0x0000ffff                                                                  /* end                  */
4112     };
4113     DWORD color;
4114     float vertex[] = {
4115        -1.0,   -1.0,    0.0,
4116         1.0,   -1.0,    1.0,
4117        -1.0,    1.0,    0.0,
4118         1.0,    1.0,    1.0
4119     };
4120
4121     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4122     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4123
4124     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4125     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4126     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4127     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4128     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4129     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4130     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4131     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4132     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4133     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4134
4135     /* Fill the depth buffer with a gradient */
4136     hr = IDirect3DDevice9_BeginScene(device);
4137     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4138     if(SUCCEEDED(hr))
4139     {
4140         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4141         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4142         hr = IDirect3DDevice9_EndScene(device);
4143         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4144     }
4145
4146     /* Now perform the actual tests. Same geometry, but with the shader */
4147     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4149     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4151     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4152     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4153
4154     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4155     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF 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, 3 * sizeof(float));
4161         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4162
4163         hr = IDirect3DDevice9_EndScene(device);
4164         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4165     }
4166
4167     color = getPixelColor(device, 158, 240);
4168     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4169     color = getPixelColor(device, 162, 240);
4170     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4171
4172     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4173     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4174
4175     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4176     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4177
4178     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4179     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4180     hr = IDirect3DDevice9_BeginScene(device);
4181     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4182     if(SUCCEEDED(hr))
4183     {
4184         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4185         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4186
4187         hr = IDirect3DDevice9_EndScene(device);
4188         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4189     }
4190
4191     color = getPixelColor(device, 318, 240);
4192     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4193     color = getPixelColor(device, 322, 240);
4194     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4195
4196     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4197     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4198
4199     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4200     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4201
4202     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4203     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4204     hr = IDirect3DDevice9_BeginScene(device);
4205     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4206     if(SUCCEEDED(hr))
4207     {
4208         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4209         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4210
4211         hr = IDirect3DDevice9_EndScene(device);
4212         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4213     }
4214
4215     color = getPixelColor(device, 1, 240);
4216     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4217
4218     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4219     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4220
4221     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4222     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4223
4224     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4225     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4226     hr = IDirect3DDevice9_BeginScene(device);
4227     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4228     if(SUCCEEDED(hr))
4229     {
4230         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4231         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4232
4233         hr = IDirect3DDevice9_EndScene(device);
4234         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4235     }
4236     color = getPixelColor(device, 318, 240);
4237     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4238     color = getPixelColor(device, 322, 240);
4239     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4240
4241     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4242     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4243
4244     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4245     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4246
4247     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4248     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4249     hr = IDirect3DDevice9_BeginScene(device);
4250     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4251     if(SUCCEEDED(hr))
4252     {
4253         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4254         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4255
4256         hr = IDirect3DDevice9_EndScene(device);
4257         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4258     }
4259
4260     color = getPixelColor(device, 1, 240);
4261     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4262
4263     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4264     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4265
4266     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4267     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4268
4269     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4270     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4271     hr = IDirect3DDevice9_BeginScene(device);
4272     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4273     if(SUCCEEDED(hr))
4274     {
4275         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4276         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4277
4278         hr = IDirect3DDevice9_EndScene(device);
4279         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4280     }
4281
4282     color = getPixelColor(device, 638, 240);
4283     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4284
4285     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4286     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4287
4288     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4289     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4290
4291     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4292     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4293     hr = IDirect3DDevice9_BeginScene(device);
4294     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4295     if(SUCCEEDED(hr))
4296     {
4297         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4298         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4299
4300         hr = IDirect3DDevice9_EndScene(device);
4301         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4302     }
4303
4304     color = getPixelColor(device, 638, 240);
4305     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4306
4307     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4308     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4309
4310     /* Cleanup */
4311     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4312     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4313     IDirect3DPixelShader9_Release(shader);
4314
4315     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4316     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4317     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4318     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4319 }
4320
4321 static void texkill_test(IDirect3DDevice9 *device)
4322 {
4323     IDirect3DPixelShader9 *shader;
4324     HRESULT hr;
4325     DWORD color;
4326
4327     const float vertex[] = {
4328     /*                          bottom  top    right    left */
4329         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4330          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4331         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4332          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4333     };
4334
4335     DWORD shader_code_11[] = {
4336     0xffff0101,                                                             /* ps_1_1                     */
4337     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4338     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4339     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4340     0x0000ffff                                                              /* end                        */
4341     };
4342     DWORD shader_code_20[] = {
4343     0xffff0200,                                                             /* ps_2_0                     */
4344     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4345     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4346     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4347     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4348     0x0000ffff                                                              /* end                        */
4349     };
4350
4351     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4352     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4353     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4354     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4355
4356     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4357     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4358     hr = IDirect3DDevice9_BeginScene(device);
4359     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4360     if(SUCCEEDED(hr))
4361     {
4362         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4363         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4365         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4366         hr = IDirect3DDevice9_EndScene(device);
4367         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4368     }
4369     color = getPixelColor(device, 63, 46);
4370     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4371     color = getPixelColor(device, 66, 46);
4372     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4373     color = getPixelColor(device, 63, 49);
4374     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4375     color = getPixelColor(device, 66, 49);
4376     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4377
4378     color = getPixelColor(device, 578, 46);
4379     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4380     color = getPixelColor(device, 575, 46);
4381     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4382     color = getPixelColor(device, 578, 49);
4383     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4384     color = getPixelColor(device, 575, 49);
4385     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4386
4387     color = getPixelColor(device, 63, 430);
4388     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4389     color = getPixelColor(device, 63, 433);
4390     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4391     color = getPixelColor(device, 66, 433);
4392     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4393     color = getPixelColor(device, 66, 430);
4394     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4395
4396     color = getPixelColor(device, 578, 430);
4397     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4398     color = getPixelColor(device, 578, 433);
4399     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4400     color = getPixelColor(device, 575, 433);
4401     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4402     color = getPixelColor(device, 575, 430);
4403     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4404
4405     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4406     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4407
4408     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4409     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4410     IDirect3DPixelShader9_Release(shader);
4411
4412     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4413     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4414     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4415     if(FAILED(hr)) {
4416         skip("Failed to create 2.0 test shader, most likely not supported\n");
4417         return;
4418     }
4419
4420     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4421     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4422     hr = IDirect3DDevice9_BeginScene(device);
4423     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4424     if(SUCCEEDED(hr))
4425     {
4426         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4427         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4428         hr = IDirect3DDevice9_EndScene(device);
4429         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4430     }
4431
4432     color = getPixelColor(device, 63, 46);
4433     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4434     color = getPixelColor(device, 66, 46);
4435     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4436     color = getPixelColor(device, 63, 49);
4437     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4438     color = getPixelColor(device, 66, 49);
4439     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4440
4441     color = getPixelColor(device, 578, 46);
4442     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4443     color = getPixelColor(device, 575, 46);
4444     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4445     color = getPixelColor(device, 578, 49);
4446     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4447     color = getPixelColor(device, 575, 49);
4448     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4449
4450     color = getPixelColor(device, 63, 430);
4451     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4452     color = getPixelColor(device, 63, 433);
4453     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4454     color = getPixelColor(device, 66, 433);
4455     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4456     color = getPixelColor(device, 66, 430);
4457     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4458
4459     color = getPixelColor(device, 578, 430);
4460     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4461     color = getPixelColor(device, 578, 433);
4462     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4463     color = getPixelColor(device, 575, 433);
4464     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4465     color = getPixelColor(device, 575, 430);
4466     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4467
4468     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4469     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4470
4471     /* Cleanup */
4472     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4473     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4474     IDirect3DPixelShader9_Release(shader);
4475 }
4476
4477 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4478 {
4479     IDirect3D9 *d3d9;
4480     HRESULT hr;
4481     IDirect3DTexture9 *texture;
4482     IDirect3DPixelShader9 *shader;
4483     IDirect3DPixelShader9 *shader2;
4484     D3DLOCKED_RECT lr;
4485     DWORD color;
4486     DWORD shader_code[] = {
4487         0xffff0101,                             /* ps_1_1       */
4488         0x00000042, 0xb00f0000,                 /* tex t0       */
4489         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4490         0x0000ffff                              /* end          */
4491     };
4492     DWORD shader_code2[] = {
4493         0xffff0101,                             /* ps_1_1       */
4494         0x00000042, 0xb00f0000,                 /* tex t0       */
4495         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4496         0x0000ffff                              /* end          */
4497     };
4498
4499     float quad[] = {
4500        -1.0,   -1.0,   0.1,     0.5,    0.5,
4501         1.0,   -1.0,   0.1,     0.5,    0.5,
4502        -1.0,    1.0,   0.1,     0.5,    0.5,
4503         1.0,    1.0,   0.1,     0.5,    0.5,
4504     };
4505
4506     memset(&lr, 0, sizeof(lr));
4507     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4508     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4509                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4510     IDirect3D9_Release(d3d9);
4511     if(FAILED(hr)) {
4512         skip("No D3DFMT_X8L8V8U8 support\n");
4513         return;
4514     };
4515
4516     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4517     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4518
4519     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4520     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4521     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4522     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4523     *((DWORD *) lr.pBits) = 0x11ca3141;
4524     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4525     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4526
4527     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4528     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4529     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4530     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4531
4532     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4533     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4534     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4535     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4536     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4537     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4538
4539     hr = IDirect3DDevice9_BeginScene(device);
4540     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4541     if(SUCCEEDED(hr))
4542     {
4543         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4544         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4545
4546         hr = IDirect3DDevice9_EndScene(device);
4547         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4548     }
4549     color = getPixelColor(device, 578, 430);
4550     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4551        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4552     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4553     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4554
4555     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4557     hr = IDirect3DDevice9_BeginScene(device);
4558     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4559     if(SUCCEEDED(hr))
4560     {
4561         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4562         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4563
4564         hr = IDirect3DDevice9_EndScene(device);
4565         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4566     }
4567     color = getPixelColor(device, 578, 430);
4568     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4569     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4570     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4571
4572     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4573     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4574     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4576     IDirect3DPixelShader9_Release(shader);
4577     IDirect3DPixelShader9_Release(shader2);
4578     IDirect3DTexture9_Release(texture);
4579 }
4580
4581 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4582 {
4583     HRESULT hr;
4584     IDirect3D9 *d3d;
4585     IDirect3DTexture9 *texture = NULL;
4586     IDirect3DSurface9 *surface;
4587     DWORD color;
4588     const RECT r1 = {256, 256, 512, 512};
4589     const RECT r2 = {512, 256, 768, 512};
4590     const RECT r3 = {256, 512, 512, 768};
4591     const RECT r4 = {512, 512, 768, 768};
4592     unsigned int x, y;
4593     D3DLOCKED_RECT lr;
4594     memset(&lr, 0, sizeof(lr));
4595
4596     IDirect3DDevice9_GetDirect3D(device, &d3d);
4597     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4598        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4599         skip("No autogenmipmap support\n");
4600         IDirect3D9_Release(d3d);
4601         return;
4602     }
4603     IDirect3D9_Release(d3d);
4604
4605     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4606     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4607
4608     /* Make the mipmap big, so that a smaller mipmap is used
4609      */
4610     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4611                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4612     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4613
4614     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4615     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4616     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4617     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4618     for(y = 0; y < 1024; y++) {
4619         for(x = 0; x < 1024; x++) {
4620             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4621             POINT pt;
4622
4623             pt.x = x;
4624             pt.y = y;
4625             if(PtInRect(&r1, pt)) {
4626                 *dst = 0xffff0000;
4627             } else if(PtInRect(&r2, pt)) {
4628                 *dst = 0xff00ff00;
4629             } else if(PtInRect(&r3, pt)) {
4630                 *dst = 0xff0000ff;
4631             } else if(PtInRect(&r4, pt)) {
4632                 *dst = 0xff000000;
4633             } else {
4634                 *dst = 0xffffffff;
4635             }
4636         }
4637     }
4638     hr = IDirect3DSurface9_UnlockRect(surface);
4639     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4640     IDirect3DSurface9_Release(surface);
4641
4642     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4643     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4644     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4645     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4646
4647     hr = IDirect3DDevice9_BeginScene(device);
4648     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4649     if(SUCCEEDED(hr)) {
4650         const float quad[] =  {
4651            -0.5,   -0.5,    0.1,    0.0,    0.0,
4652            -0.5,    0.5,    0.1,    0.0,    1.0,
4653             0.5,   -0.5,    0.1,    1.0,    0.0,
4654             0.5,    0.5,    0.1,    1.0,    1.0
4655         };
4656
4657         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4658         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4659         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4660         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4661         hr = IDirect3DDevice9_EndScene(device);
4662         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4663     }
4664     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4665     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4666     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4667     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4668     IDirect3DTexture9_Release(texture);
4669
4670     color = getPixelColor(device, 200, 200);
4671     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4672     color = getPixelColor(device, 280, 200);
4673     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4674     color = getPixelColor(device, 360, 200);
4675     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4676     color = getPixelColor(device, 440, 200);
4677     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4678     color = getPixelColor(device, 200, 270);
4679     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4680     color = getPixelColor(device, 280, 270);
4681     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4682     color = getPixelColor(device, 360, 270);
4683     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4684     color = getPixelColor(device, 440, 270);
4685     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4686     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4687     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4688 }
4689
4690 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4691 {
4692     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4693     IDirect3DVertexDeclaration9 *decl;
4694     HRESULT hr;
4695     DWORD color;
4696     DWORD shader_code_11[] =  {
4697         0xfffe0101,                                         /* vs_1_1           */
4698         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4699         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4700         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4701         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4702         0x0000ffff                                          /* end              */
4703     };
4704     DWORD shader_code_11_2[] =  {
4705         0xfffe0101,                                         /* vs_1_1           */
4706         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4707         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4708         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4709         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4710         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4711         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4712         0x0000ffff                                          /* end              */
4713     };
4714     DWORD shader_code_20[] =  {
4715         0xfffe0200,                                         /* vs_2_0           */
4716         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4717         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4718         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4719         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4720         0x0000ffff                                          /* end              */
4721     };
4722     DWORD shader_code_20_2[] =  {
4723         0xfffe0200,                                         /* vs_2_0           */
4724         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4725         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4726         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4727         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4728         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4729         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4730         0x0000ffff                                          /* end              */
4731     };
4732     static const D3DVERTEXELEMENT9 decl_elements[] = {
4733         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4734         D3DDECL_END()
4735     };
4736     float quad1[] = {
4737         -1.0,   -1.0,   0.1,
4738          0.0,   -1.0,   0.1,
4739         -1.0,    0.0,   0.1,
4740          0.0,    0.0,   0.1
4741     };
4742     float quad2[] = {
4743          0.0,   -1.0,   0.1,
4744          1.0,   -1.0,   0.1,
4745          0.0,    0.0,   0.1,
4746          1.0,    0.0,   0.1
4747     };
4748     float quad3[] = {
4749          0.0,    0.0,   0.1,
4750          1.0,    0.0,   0.1,
4751          0.0,    1.0,   0.1,
4752          1.0,    1.0,   0.1
4753     };
4754     float quad4[] = {
4755         -1.0,    0.0,   0.1,
4756          0.0,    0.0,   0.1,
4757         -1.0,    1.0,   0.1,
4758          0.0,    1.0,   0.1
4759     };
4760     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4761     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4762
4763     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4764     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4765
4766     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4767     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4768     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4769     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4770     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4771     if(FAILED(hr)) shader_20 = NULL;
4772     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4773     if(FAILED(hr)) shader_20_2 = NULL;
4774     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4775     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4776
4777     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4778     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4779     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4780     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4781     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4782     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4783
4784     hr = IDirect3DDevice9_BeginScene(device);
4785     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4786     if(SUCCEEDED(hr))
4787     {
4788         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4789         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4791         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792
4793         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4794         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4795         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4796         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4797
4798         if(shader_20) {
4799             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4800             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4801             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4802             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4803         }
4804
4805         if(shader_20_2) {
4806             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4807             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4808             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4809             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4810         }
4811
4812         hr = IDirect3DDevice9_EndScene(device);
4813         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4814     }
4815
4816     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4817     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4818     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4819     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4820
4821     color = getPixelColor(device, 160, 360);
4822     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4823        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4824     color = getPixelColor(device, 480, 360);
4825     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4826        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4827     if(shader_20) {
4828         color = getPixelColor(device, 480, 120);
4829         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4830            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4831     }
4832     if(shader_20_2) {
4833         color = getPixelColor(device, 160, 120);
4834         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4835            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4836     }
4837     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4839
4840     IDirect3DVertexDeclaration9_Release(decl);
4841     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4842     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4843     IDirect3DVertexShader9_Release(shader_11_2);
4844     IDirect3DVertexShader9_Release(shader_11);
4845 }
4846
4847 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4848 {
4849     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4850     HRESULT hr;
4851     DWORD color;
4852     DWORD shader_code_11[] =  {
4853         0xffff0101,                                         /* ps_1_1           */
4854         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4855         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4856         0x0000ffff                                          /* end              */
4857     };
4858     DWORD shader_code_12[] =  {
4859         0xffff0102,                                         /* ps_1_2           */
4860         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4861         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4862         0x0000ffff                                          /* end              */
4863     };
4864     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4865      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4866      * During development of this test, 1.3 shaders were verified too
4867      */
4868     DWORD shader_code_14[] =  {
4869         0xffff0104,                                         /* ps_1_4           */
4870         /* Try to make one constant local. It gets clamped too, although the binary contains
4871          * the bigger numbers
4872          */
4873         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4874         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4875         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4876         0x0000ffff                                          /* end              */
4877     };
4878     DWORD shader_code_20[] =  {
4879         0xffff0200,                                         /* ps_2_0           */
4880         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4881         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4882         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4883         0x0000ffff                                          /* end              */
4884     };
4885     float quad1[] = {
4886         -1.0,   -1.0,   0.1,
4887          0.0,   -1.0,   0.1,
4888         -1.0,    0.0,   0.1,
4889          0.0,    0.0,   0.1
4890     };
4891     float quad2[] = {
4892          0.0,   -1.0,   0.1,
4893          1.0,   -1.0,   0.1,
4894          0.0,    0.0,   0.1,
4895          1.0,    0.0,   0.1
4896     };
4897     float quad3[] = {
4898          0.0,    0.0,   0.1,
4899          1.0,    0.0,   0.1,
4900          0.0,    1.0,   0.1,
4901          1.0,    1.0,   0.1
4902     };
4903     float quad4[] = {
4904         -1.0,    0.0,   0.1,
4905          0.0,    0.0,   0.1,
4906         -1.0,    1.0,   0.1,
4907          0.0,    1.0,   0.1
4908     };
4909     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4910     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4911
4912     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4913     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4914
4915     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4916     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4917     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4918     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4919     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4920     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4921     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4922     if(FAILED(hr)) shader_20 = NULL;
4923
4924     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4925     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4926     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4927     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4928     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4929     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4930
4931     hr = IDirect3DDevice9_BeginScene(device);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4933     if(SUCCEEDED(hr))
4934     {
4935         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4936         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4937         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4938         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4939
4940         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4941         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4942         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4943         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4944
4945         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4946         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4947         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4948         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4949
4950         if(shader_20) {
4951             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4952             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4953             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4954             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4955         }
4956
4957         hr = IDirect3DDevice9_EndScene(device);
4958         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4959     }
4960     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4961     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4962
4963     color = getPixelColor(device, 160, 360);
4964     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4965        "quad 1 has color %08x, expected 0x00808000\n", color);
4966     color = getPixelColor(device, 480, 360);
4967     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4968        "quad 2 has color %08x, expected 0x00808000\n", color);
4969     color = getPixelColor(device, 480, 120);
4970     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4971        "quad 3 has color %08x, expected 0x00808000\n", color);
4972     if(shader_20) {
4973         color = getPixelColor(device, 160, 120);
4974         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4975            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4976     }
4977     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4978     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4979
4980     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4981     IDirect3DPixelShader9_Release(shader_14);
4982     IDirect3DPixelShader9_Release(shader_12);
4983     IDirect3DPixelShader9_Release(shader_11);
4984 }
4985
4986 static void dp2add_ps_test(IDirect3DDevice9 *device)
4987 {
4988     IDirect3DPixelShader9 *shader_dp2add = NULL;
4989     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4990     HRESULT hr;
4991     DWORD color;
4992
4993     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
4994      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4995      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
4996      * r0 first.
4997      * The result here for the r,g,b components should be roughly 0.5:
4998      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4999     static const DWORD shader_code_dp2add[] =  {
5000         0xffff0200,                                                             /* ps_2_0                       */
5001         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5002
5003         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5004         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5005
5006         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5007         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5008         0x0000ffff                                                              /* end                          */
5009     };
5010
5011     /* Test the _sat modifier, too.  Result here should be:
5012      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5013      *      _SAT: ==> 1.0
5014      *   ADD: (1.0 + -0.5) = 0.5
5015      */
5016     static const DWORD shader_code_dp2add_sat[] =  {
5017         0xffff0200,                                                             /* ps_2_0                           */
5018         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5019
5020         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5021         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5022         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5023
5024         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5025         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5026         0x0000ffff                                                              /* end                              */
5027     };
5028
5029     const float quad[] = {
5030         -1.0,   -1.0,   0.1,
5031          1.0,   -1.0,   0.1,
5032         -1.0,    1.0,   0.1,
5033          1.0,    1.0,   0.1
5034     };
5035
5036
5037     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5038     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5039
5040     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5041     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5042
5043     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5044     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5045
5046     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5047     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5048
5049     if (shader_dp2add) {
5050
5051         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5052         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5053
5054         hr = IDirect3DDevice9_BeginScene(device);
5055         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5056         if(SUCCEEDED(hr))
5057         {
5058             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5059             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5060
5061             hr = IDirect3DDevice9_EndScene(device);
5062             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5063         }
5064
5065         color = getPixelColor(device, 360, 240);
5066         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5067                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5068
5069         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5070         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5071
5072         IDirect3DPixelShader9_Release(shader_dp2add);
5073     } else {
5074         skip("dp2add shader creation failed\n");
5075     }
5076
5077     if (shader_dp2add_sat) {
5078
5079         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5080         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5081
5082         hr = IDirect3DDevice9_BeginScene(device);
5083         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5084         if(SUCCEEDED(hr))
5085         {
5086             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5087             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5088
5089             hr = IDirect3DDevice9_EndScene(device);
5090             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5091         }
5092
5093         color = getPixelColor(device, 360, 240);
5094         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5095                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5096
5097         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5098         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5099
5100         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5101     } else {
5102         skip("dp2add shader creation failed\n");
5103     }
5104
5105     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5106     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5107 }
5108
5109 static void cnd_test(IDirect3DDevice9 *device)
5110 {
5111     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5112     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5113     HRESULT hr;
5114     DWORD color;
5115     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5116      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5117      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5118      */
5119     DWORD shader_code_11[] =  {
5120         0xffff0101,                                                                 /* ps_1_1               */
5121         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5122         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5123         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5124         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5125         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5126         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5127         0x0000ffff                                                                  /* end                  */
5128     };
5129     DWORD shader_code_12[] =  {
5130         0xffff0102,                                                                 /* ps_1_2               */
5131         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5132         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5133         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5134         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5135         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5136         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5137         0x0000ffff                                                                  /* end                  */
5138     };
5139     DWORD shader_code_13[] =  {
5140         0xffff0103,                                                                 /* ps_1_3               */
5141         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5142         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5143         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5144         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5145         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5146         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5147         0x0000ffff                                                                  /* end                  */
5148     };
5149     DWORD shader_code_14[] =  {
5150         0xffff0104,                                                                 /* ps_1_3               */
5151         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5152         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5153         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5154         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5155         0x0000ffff                                                                  /* end                  */
5156     };
5157
5158     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5159      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5160      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5161      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5162      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5163      * good enough.
5164      *
5165      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5166      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5167      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5168      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5169      */
5170     DWORD shader_code_11_coissue[] =  {
5171         0xffff0101,                                                             /* ps_1_1                   */
5172         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5173         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5174         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5175         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5176         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5177         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5178         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5179         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5180         /* 0x40000000 = D3DSI_COISSUE */
5181         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5182         0x0000ffff                                                              /* end                      */
5183     };
5184     DWORD shader_code_12_coissue[] =  {
5185         0xffff0102,                                                             /* ps_1_2                   */
5186         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5187         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5188         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5189         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5190         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5191         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5192         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5193         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5194         /* 0x40000000 = D3DSI_COISSUE */
5195         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5196         0x0000ffff                                                              /* end                      */
5197     };
5198     DWORD shader_code_13_coissue[] =  {
5199         0xffff0103,                                                             /* ps_1_3                   */
5200         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5201         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5202         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5203         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5204         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5205         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5206         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5207         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5208         /* 0x40000000 = D3DSI_COISSUE */
5209         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5210         0x0000ffff                                                              /* end                      */
5211     };
5212     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5213      * compare against 0.5
5214      */
5215     DWORD shader_code_14_coissue[] =  {
5216         0xffff0104,                                                             /* ps_1_4                   */
5217         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5218         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5219         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5220         /* 0x40000000 = D3DSI_COISSUE */
5221         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5222         0x0000ffff                                                              /* end                      */
5223     };
5224     float quad1[] = {
5225         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5226          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5227         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5228          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5229     };
5230     float quad2[] = {
5231          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5232          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5233          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5234          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5235     };
5236     float quad3[] = {
5237          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5238          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5239          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5240          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5241     };
5242     float quad4[] = {
5243         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5244          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5245         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5246          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5247     };
5248     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5249     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5250     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5251     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5252
5253     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5254     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5255
5256     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5257     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5258     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5259     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5260     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5261     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5262     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5263     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5264     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5265     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5266     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5267     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5268     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5269     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5270     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5271     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5272
5273     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5274     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5275     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5276     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5277     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5278     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5279
5280     hr = IDirect3DDevice9_BeginScene(device);
5281     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5282     if(SUCCEEDED(hr))
5283     {
5284         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5285         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5286         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5287         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5288
5289         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5290         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5291         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5292         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5293
5294         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5295         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5296         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5297         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5298
5299         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5300         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5301         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5302         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5303
5304         hr = IDirect3DDevice9_EndScene(device);
5305         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5306     }
5307
5308     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5309     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5310
5311     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5312     color = getPixelColor(device, 158, 118);
5313     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5314     color = getPixelColor(device, 162, 118);
5315     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5316     color = getPixelColor(device, 158, 122);
5317     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5318     color = getPixelColor(device, 162, 122);
5319     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5320
5321     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5322     color = getPixelColor(device, 158, 358);
5323     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5324     color = getPixelColor(device, 162, 358);
5325     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5326         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5327     color = getPixelColor(device, 158, 362);
5328     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5329     color = getPixelColor(device, 162, 362);
5330     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5331         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5332
5333     /* 1.2 shader */
5334     color = getPixelColor(device, 478, 358);
5335     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5336     color = getPixelColor(device, 482, 358);
5337     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5338         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5339     color = getPixelColor(device, 478, 362);
5340     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5341     color = getPixelColor(device, 482, 362);
5342     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5343         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5344
5345     /* 1.3 shader */
5346     color = getPixelColor(device, 478, 118);
5347     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5348     color = getPixelColor(device, 482, 118);
5349     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5350         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5351     color = getPixelColor(device, 478, 122);
5352     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5353     color = getPixelColor(device, 482, 122);
5354     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5355         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5356
5357     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5358     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5359
5360     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5361     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5362     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5363     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5364     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5365     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5366
5367     hr = IDirect3DDevice9_BeginScene(device);
5368     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5369     if(SUCCEEDED(hr))
5370     {
5371         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5372         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5373         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5374         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5375
5376         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5377         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5378         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5379         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5380
5381         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5382         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5384         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5385
5386         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5387         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5388         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5389         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5390
5391         hr = IDirect3DDevice9_EndScene(device);
5392         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5393     }
5394
5395     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5396     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5397
5398     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5399      * that we swapped the values in c1 and c2 to make the other tests return some color
5400      */
5401     color = getPixelColor(device, 158, 118);
5402     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5403     color = getPixelColor(device, 162, 118);
5404     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5405     color = getPixelColor(device, 158, 122);
5406     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5407     color = getPixelColor(device, 162, 122);
5408     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5409
5410     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5411      * (The Win7 nvidia driver always selects c2)
5412      */
5413     color = getPixelColor(device, 158, 358);
5414     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5415         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5416     color = getPixelColor(device, 162, 358);
5417     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5418         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5419     color = getPixelColor(device, 158, 362);
5420     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5421         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5422     color = getPixelColor(device, 162, 362);
5423     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5424         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5425
5426     /* 1.2 shader */
5427     color = getPixelColor(device, 478, 358);
5428     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5429         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5430     color = getPixelColor(device, 482, 358);
5431     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5432         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5433     color = getPixelColor(device, 478, 362);
5434     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5435         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5436     color = getPixelColor(device, 482, 362);
5437     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5438         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5439
5440     /* 1.3 shader */
5441     color = getPixelColor(device, 478, 118);
5442     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5443         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5444     color = getPixelColor(device, 482, 118);
5445     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5446         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5447     color = getPixelColor(device, 478, 122);
5448     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5449         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5450     color = getPixelColor(device, 482, 122);
5451     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5452         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5453
5454     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5455     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5456
5457     IDirect3DPixelShader9_Release(shader_14_coissue);
5458     IDirect3DPixelShader9_Release(shader_13_coissue);
5459     IDirect3DPixelShader9_Release(shader_12_coissue);
5460     IDirect3DPixelShader9_Release(shader_11_coissue);
5461     IDirect3DPixelShader9_Release(shader_14);
5462     IDirect3DPixelShader9_Release(shader_13);
5463     IDirect3DPixelShader9_Release(shader_12);
5464     IDirect3DPixelShader9_Release(shader_11);
5465 }
5466
5467 static void nested_loop_test(IDirect3DDevice9 *device) {
5468     const DWORD shader_code[] = {
5469         0xffff0300,                                                             /* ps_3_0               */
5470         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5471         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5472         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5473         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5474         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5475         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5476         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5477         0x0000001d,                                                             /* endloop              */
5478         0x0000001d,                                                             /* endloop              */
5479         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5480         0x0000ffff                                                              /* end                  */
5481     };
5482     const DWORD vshader_code[] = {
5483         0xfffe0300,                                                             /* vs_3_0               */
5484         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5485         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5486         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5487         0x0000ffff                                                              /* end                  */
5488     };
5489     IDirect3DPixelShader9 *shader;
5490     IDirect3DVertexShader9 *vshader;
5491     HRESULT hr;
5492     DWORD color;
5493     const float quad[] = {
5494         -1.0,   -1.0,   0.1,
5495          1.0,   -1.0,   0.1,
5496         -1.0,    1.0,   0.1,
5497          1.0,    1.0,   0.1
5498     };
5499
5500     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5501     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5502     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5503     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5504     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5506     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5507     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5508     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5509     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5510     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5511     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5512
5513     hr = IDirect3DDevice9_BeginScene(device);
5514     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5515     if(SUCCEEDED(hr))
5516     {
5517         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5518         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5519         hr = IDirect3DDevice9_EndScene(device);
5520         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5521     }
5522
5523     color = getPixelColor(device, 360, 240);
5524     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5525        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5526
5527     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5528     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5529
5530     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5531     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5532     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5533     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5534     IDirect3DPixelShader9_Release(shader);
5535     IDirect3DVertexShader9_Release(vshader);
5536 }
5537
5538 struct varying_test_struct
5539 {
5540     const DWORD             *shader_code;
5541     IDirect3DPixelShader9   *shader;
5542     DWORD                   color, color_rhw;
5543     const char              *name;
5544     BOOL                    todo, todo_rhw;
5545 };
5546
5547 struct hugeVertex
5548 {
5549     float pos_x,        pos_y,      pos_z,      rhw;
5550     float weight_1,     weight_2,   weight_3,   weight_4;
5551     float index_1,      index_2,    index_3,    index_4;
5552     float normal_1,     normal_2,   normal_3,   normal_4;
5553     float fog_1,        fog_2,      fog_3,      fog_4;
5554     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5555     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5556     float binormal_1,   binormal_2, binormal_3, binormal_4;
5557     float depth_1,      depth_2,    depth_3,    depth_4;
5558     DWORD diffuse, specular;
5559 };
5560
5561 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5562     /* dcl_position: fails to compile */
5563     const DWORD blendweight_code[] = {
5564         0xffff0300,                             /* ps_3_0                   */
5565         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5566         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5567         0x0000ffff                              /* end                      */
5568     };
5569     const DWORD blendindices_code[] = {
5570         0xffff0300,                             /* ps_3_0                   */
5571         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5572         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5573         0x0000ffff                              /* end                      */
5574     };
5575     const DWORD normal_code[] = {
5576         0xffff0300,                             /* ps_3_0                   */
5577         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5578         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5579         0x0000ffff                              /* end                      */
5580     };
5581     /* psize: fails? */
5582     const DWORD texcoord0_code[] = {
5583         0xffff0300,                             /* ps_3_0                   */
5584         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5585         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5586         0x0000ffff                              /* end                      */
5587     };
5588     const DWORD tangent_code[] = {
5589         0xffff0300,                             /* ps_3_0                   */
5590         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5591         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5592         0x0000ffff                              /* end                      */
5593     };
5594     const DWORD binormal_code[] = {
5595         0xffff0300,                             /* ps_3_0                   */
5596         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5597         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5598         0x0000ffff                              /* end                      */
5599     };
5600     /* tessfactor: fails */
5601     /* positiont: fails */
5602     const DWORD color_code[] = {
5603         0xffff0300,                             /* ps_3_0                   */
5604         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5605         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5606         0x0000ffff                              /* end                      */
5607     };
5608     const DWORD fog_code[] = {
5609         0xffff0300,                             /* ps_3_0                   */
5610         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5611         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5612         0x0000ffff                              /* end                      */
5613     };
5614     const DWORD depth_code[] = {
5615         0xffff0300,                             /* ps_3_0                   */
5616         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5617         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5618         0x0000ffff                              /* end                      */
5619     };
5620     const DWORD specular_code[] = {
5621         0xffff0300,                             /* ps_3_0                   */
5622         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5623         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5624         0x0000ffff                              /* end                      */
5625     };
5626     /* sample: fails */
5627
5628     struct varying_test_struct tests[] = {
5629        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5630        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5631        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5632        /* Why does dx not forward the texcoord? */
5633        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5634        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5635        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5636        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5637        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5638        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5639        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5640     };
5641     /* Declare a monster vertex type :-) */
5642     static const D3DVERTEXELEMENT9 decl_elements[] = {
5643         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5644         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5645         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5646         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5647         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5648         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5649         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5650         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5651         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5652         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5653         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5654         D3DDECL_END()
5655     };
5656     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5657         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5658         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5659         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5660         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5661         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5662         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5663         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5664         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5665         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5666         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5667         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5668         D3DDECL_END()
5669     };
5670     struct hugeVertex data[4] = {
5671         {
5672             -1.0,   -1.0,   0.1,    1.0,
5673              0.1,    0.1,   0.1,    0.1,
5674              0.2,    0.2,   0.2,    0.2,
5675              0.3,    0.3,   0.3,    0.3,
5676              0.4,    0.4,   0.4,    0.4,
5677              0.50,   0.55,  0.55,   0.55,
5678              0.6,    0.6,   0.6,    0.7,
5679              0.7,    0.7,   0.7,    0.6,
5680              0.8,    0.8,   0.8,    0.8,
5681              0xe6e6e6e6, /* 0.9 * 256 */
5682              0x224488ff  /* Nothing special */
5683         },
5684         {
5685              1.0,   -1.0,   0.1,    1.0,
5686              0.1,    0.1,   0.1,    0.1,
5687              0.2,    0.2,   0.2,    0.2,
5688              0.3,    0.3,   0.3,    0.3,
5689              0.4,    0.4,   0.4,    0.4,
5690              0.50,   0.55,  0.55,   0.55,
5691              0.6,    0.6,   0.6,    0.7,
5692              0.7,    0.7,   0.7,    0.6,
5693              0.8,    0.8,   0.8,    0.8,
5694              0xe6e6e6e6, /* 0.9 * 256 */
5695              0x224488ff /* Nothing special */
5696         },
5697         {
5698             -1.0,    1.0,   0.1,    1.0,
5699              0.1,    0.1,   0.1,    0.1,
5700              0.2,    0.2,   0.2,    0.2,
5701              0.3,    0.3,   0.3,    0.3,
5702              0.4,    0.4,   0.4,    0.4,
5703              0.50,   0.55,  0.55,   0.55,
5704              0.6,    0.6,   0.6,    0.7,
5705              0.7,    0.7,   0.7,    0.6,
5706              0.8,    0.8,   0.8,    0.8,
5707              0xe6e6e6e6, /* 0.9 * 256 */
5708              0x224488ff /* Nothing special */
5709         },
5710         {
5711              1.0,    1.0,   0.1,    1.0,
5712              0.1,    0.1,   0.1,    0.1,
5713              0.2,    0.2,   0.2,    0.2,
5714              0.3,    0.3,   0.3,    0.3,
5715              0.4,    0.4,   0.4,    0.4,
5716              0.50,   0.55,  0.55,   0.55,
5717              0.6,    0.6,   0.6,    0.7,
5718              0.7,    0.7,   0.7,    0.6,
5719              0.8,    0.8,   0.8,    0.8,
5720              0xe6e6e6e6, /* 0.9 * 256 */
5721              0x224488ff /* Nothing special */
5722         },
5723     };
5724     struct hugeVertex data2[4];
5725     IDirect3DVertexDeclaration9 *decl;
5726     IDirect3DVertexDeclaration9 *decl2;
5727     HRESULT hr;
5728     unsigned int i;
5729     DWORD color, r, g, b, r_e, g_e, b_e;
5730     BOOL drawok;
5731
5732     memcpy(data2, data, sizeof(data2));
5733     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5734     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5735     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5736     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5737
5738     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5739     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5740     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5741     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5742     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5743     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5744
5745     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5746     {
5747         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5748         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5749            tests[i].name, hr);
5750     }
5751
5752     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5753     {
5754         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5755         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5756
5757         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5758         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5759
5760         hr = IDirect3DDevice9_BeginScene(device);
5761         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5762         drawok = FALSE;
5763         if(SUCCEEDED(hr))
5764         {
5765             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5766             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5767             drawok = SUCCEEDED(hr);
5768             hr = IDirect3DDevice9_EndScene(device);
5769             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5770         }
5771
5772         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5773          * the failure and do not check the color if it failed
5774          */
5775         if(!drawok) {
5776             continue;
5777         }
5778
5779         color = getPixelColor(device, 360, 240);
5780         r = color & 0x00ff0000 >> 16;
5781         g = color & 0x0000ff00 >>  8;
5782         b = color & 0x000000ff;
5783         r_e = tests[i].color & 0x00ff0000 >> 16;
5784         g_e = tests[i].color & 0x0000ff00 >>  8;
5785         b_e = tests[i].color & 0x000000ff;
5786
5787         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5788         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5789
5790         if(tests[i].todo) {
5791             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5792                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5793                          tests[i].name, color, tests[i].color);
5794         } else {
5795             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5796                "Test %s returned color 0x%08x, expected 0x%08x\n",
5797                tests[i].name, color, tests[i].color);
5798         }
5799     }
5800
5801     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5802     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5803     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5804     {
5805         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5806         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5807
5808         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5809         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5810
5811         hr = IDirect3DDevice9_BeginScene(device);
5812         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5813         if(SUCCEEDED(hr))
5814         {
5815             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5816             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5817             hr = IDirect3DDevice9_EndScene(device);
5818             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5819         }
5820
5821         color = getPixelColor(device, 360, 240);
5822         r = color & 0x00ff0000 >> 16;
5823         g = color & 0x0000ff00 >>  8;
5824         b = color & 0x000000ff;
5825         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5826         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5827         b_e = tests[i].color_rhw & 0x000000ff;
5828
5829         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5830         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5831
5832         if(tests[i].todo_rhw) {
5833             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5834              * pipeline
5835              */
5836             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5837                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5838                          tests[i].name, color, tests[i].color_rhw);
5839         } else {
5840             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5841                "Test %s returned color 0x%08x, expected 0x%08x\n",
5842                tests[i].name, color, tests[i].color_rhw);
5843         }
5844     }
5845
5846     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5847     {
5848         IDirect3DPixelShader9_Release(tests[i].shader);
5849     }
5850
5851     IDirect3DVertexDeclaration9_Release(decl2);
5852     IDirect3DVertexDeclaration9_Release(decl);
5853 }
5854
5855 static void test_compare_instructions(IDirect3DDevice9 *device)
5856 {
5857     DWORD shader_sge_vec_code[] = {
5858         0xfffe0101,                                         /* vs_1_1                   */
5859         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5860         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5861         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5862         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5863         0x0000ffff                                          /* end                      */
5864     };
5865     DWORD shader_slt_vec_code[] = {
5866         0xfffe0101,                                         /* vs_1_1                   */
5867         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5868         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5869         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5870         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5871         0x0000ffff                                          /* end                      */
5872     };
5873     DWORD shader_sge_scalar_code[] = {
5874         0xfffe0101,                                         /* vs_1_1                   */
5875         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5876         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5877         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5878         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5879         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5880         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5881         0x0000ffff                                          /* end                      */
5882     };
5883     DWORD shader_slt_scalar_code[] = {
5884         0xfffe0101,                                         /* vs_1_1                   */
5885         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5886         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5887         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5888         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5889         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5890         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5891         0x0000ffff                                          /* end                      */
5892     };
5893     IDirect3DVertexShader9 *shader_sge_vec;
5894     IDirect3DVertexShader9 *shader_slt_vec;
5895     IDirect3DVertexShader9 *shader_sge_scalar;
5896     IDirect3DVertexShader9 *shader_slt_scalar;
5897     HRESULT hr, color;
5898     float quad1[] =  {
5899         -1.0,   -1.0,   0.1,
5900          0.0,   -1.0,   0.1,
5901         -1.0,    0.0,   0.1,
5902          0.0,    0.0,   0.1
5903     };
5904     float quad2[] =  {
5905          0.0,   -1.0,   0.1,
5906          1.0,   -1.0,   0.1,
5907          0.0,    0.0,   0.1,
5908          1.0,    0.0,   0.1
5909     };
5910     float quad3[] =  {
5911         -1.0,    0.0,   0.1,
5912          0.0,    0.0,   0.1,
5913         -1.0,    1.0,   0.1,
5914          0.0,    1.0,   0.1
5915     };
5916     float quad4[] =  {
5917          0.0,    0.0,   0.1,
5918          1.0,    0.0,   0.1,
5919          0.0,    1.0,   0.1,
5920          1.0,    1.0,   0.1
5921     };
5922     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5923     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5924
5925     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5926     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5927
5928     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5929     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5930     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5931     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5932     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5933     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5934     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5935     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5936     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5937     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5938     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5939     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5940     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5941     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5942
5943     hr = IDirect3DDevice9_BeginScene(device);
5944     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5945     if(SUCCEEDED(hr))
5946     {
5947         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5948         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5949         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5950         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5951
5952         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5953         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5954         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5955         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5956
5957         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5958         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5959         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5960         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5961
5962         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5963         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5964
5965         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5966         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5967         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5968         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5969
5970         hr = IDirect3DDevice9_EndScene(device);
5971         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5972     }
5973
5974     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5975     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5976
5977     color = getPixelColor(device, 160, 360);
5978     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5979     color = getPixelColor(device, 480, 360);
5980     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5981     color = getPixelColor(device, 160, 120);
5982     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5983     color = getPixelColor(device, 480, 160);
5984     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5985
5986     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5987     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5988
5989     IDirect3DVertexShader9_Release(shader_sge_vec);
5990     IDirect3DVertexShader9_Release(shader_slt_vec);
5991     IDirect3DVertexShader9_Release(shader_sge_scalar);
5992     IDirect3DVertexShader9_Release(shader_slt_scalar);
5993 }
5994
5995 static void test_vshader_input(IDirect3DDevice9 *device)
5996 {
5997     DWORD swapped_shader_code_3[] = {
5998         0xfffe0300,                                         /* vs_3_0               */
5999         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6000         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6001         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6002         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6003         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6004         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6005         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6006         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6007         0x0000ffff                                          /* end                  */
6008     };
6009     DWORD swapped_shader_code_1[] = {
6010         0xfffe0101,                                         /* vs_1_1               */
6011         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6012         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6013         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6014         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6015         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6016         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6017         0x0000ffff                                          /* end                  */
6018     };
6019     DWORD swapped_shader_code_2[] = {
6020         0xfffe0200,                                         /* vs_2_0               */
6021         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6022         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6023         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6024         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6025         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6026         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6027         0x0000ffff                                          /* end                  */
6028     };
6029     DWORD texcoord_color_shader_code_3[] = {
6030         0xfffe0300,                                         /* vs_3_0               */
6031         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6032         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6033         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6034         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6035         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6036         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6037         0x0000ffff                                          /* end                  */
6038     };
6039     DWORD texcoord_color_shader_code_2[] = {
6040         0xfffe0200,                                         /* vs_2_0               */
6041         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6042         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6043         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6044         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6045         0x0000ffff                                          /* end                  */
6046     };
6047     DWORD texcoord_color_shader_code_1[] = {
6048         0xfffe0101,                                         /* vs_1_1               */
6049         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6050         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6051         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6052         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6053         0x0000ffff                                          /* end                  */
6054     };
6055     DWORD color_color_shader_code_3[] = {
6056         0xfffe0300,                                         /* vs_3_0               */
6057         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6058         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6059         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6060         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6061         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6062         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6063         0x0000ffff                                          /* end                  */
6064     };
6065     DWORD color_color_shader_code_2[] = {
6066         0xfffe0200,                                         /* vs_2_0               */
6067         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6068         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6069         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6070         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6071         0x0000ffff                                          /* end                  */
6072     };
6073     DWORD color_color_shader_code_1[] = {
6074         0xfffe0101,                                         /* vs_1_1               */
6075         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6076         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6077         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6078         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6079         0x0000ffff                                          /* end                  */
6080     };
6081     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6082     HRESULT hr;
6083     DWORD color;
6084     float quad1[] =  {
6085         -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6086          0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6087         -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6088          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6089     };
6090     float quad2[] =  {
6091          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6092          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6093          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6094          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6095     };
6096     float quad3[] =  {
6097         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6098          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6099         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6100          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6101     };
6102     float quad4[] =  {
6103          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6104          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6105          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6106          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6107     };
6108     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6109         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6110         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6111         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6112         D3DDECL_END()
6113     };
6114     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6115         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6116         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6117         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6118         D3DDECL_END()
6119     };
6120     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6121         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6122         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6123         D3DDECL_END()
6124     };
6125     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6126         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6127         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6128         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6129         D3DDECL_END()
6130     };
6131     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6132         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6133         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6134         D3DDECL_END()
6135     };
6136     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6137         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6138         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6139         D3DDECL_END()
6140     };
6141     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6142         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6143         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6144         D3DDECL_END()
6145     };
6146     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6147         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6148         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6149         D3DDECL_END()
6150     };
6151     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6152     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6153     unsigned int i;
6154     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6155     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6156
6157     struct vertex quad1_color[] =  {
6158        {-1.0,   -1.0,   0.1,    0x00ff8040},
6159        { 0.0,   -1.0,   0.1,    0x00ff8040},
6160        {-1.0,    0.0,   0.1,    0x00ff8040},
6161        { 0.0,    0.0,   0.1,    0x00ff8040}
6162     };
6163     struct vertex quad2_color[] =  {
6164        { 0.0,   -1.0,   0.1,    0x00ff8040},
6165        { 1.0,   -1.0,   0.1,    0x00ff8040},
6166        { 0.0,    0.0,   0.1,    0x00ff8040},
6167        { 1.0,    0.0,   0.1,    0x00ff8040}
6168     };
6169     struct vertex quad3_color[] =  {
6170        {-1.0,    0.0,   0.1,    0x00ff8040},
6171        { 0.0,    0.0,   0.1,    0x00ff8040},
6172        {-1.0,    1.0,   0.1,    0x00ff8040},
6173        { 0.0,    1.0,   0.1,    0x00ff8040}
6174     };
6175     float quad4_color[] =  {
6176          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6177          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6178          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6179          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6180     };
6181
6182     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6183     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6184     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6185     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6186     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6187     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6188     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6189     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6190
6191     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6192     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6193     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6194     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6195     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6196     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6197     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6198     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6199
6200     for(i = 1; i <= 3; i++) {
6201         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6202         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6203         if(i == 3) {
6204             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6205             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6206         } else if(i == 2){
6207             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6208             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6209         } else if(i == 1) {
6210             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6211             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6212         }
6213
6214         hr = IDirect3DDevice9_BeginScene(device);
6215         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6216         if(SUCCEEDED(hr))
6217         {
6218             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6219             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6220
6221             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6222             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6223             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6224             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6225
6226             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6227             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6228             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6229             if(i == 3 || i == 2) {
6230                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6231             } else if(i == 1) {
6232                 /* Succeeds or fails, depending on SW or HW vertex processing */
6233                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6234             }
6235
6236             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6237             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6238             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6239             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6240
6241             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6242             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6243             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6244             if(i == 3 || i == 2) {
6245                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6246             } else if(i == 1) {
6247                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6248             }
6249
6250             hr = IDirect3DDevice9_EndScene(device);
6251             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6252         }
6253
6254         if(i == 3 || i == 2) {
6255             color = getPixelColor(device, 160, 360);
6256             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6257                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6258
6259             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6260             color = getPixelColor(device, 480, 360);
6261             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6262                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6263             color = getPixelColor(device, 160, 120);
6264             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6265             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6266                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6267
6268             color = getPixelColor(device, 480, 160);
6269             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6270         } else if(i == 1) {
6271             color = getPixelColor(device, 160, 360);
6272             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6273                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6274             color = getPixelColor(device, 480, 360);
6275             /* Accept the clear color as well in this case, since SW VP returns an error */
6276             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6277             color = getPixelColor(device, 160, 120);
6278             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6279                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6280             color = getPixelColor(device, 480, 160);
6281             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6282         }
6283
6284         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6285         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6286
6287         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6288         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6289
6290         /* Now find out if the whole streams are re-read, or just the last active value for the
6291          * vertices is used.
6292          */
6293         hr = IDirect3DDevice9_BeginScene(device);
6294         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295         if(SUCCEEDED(hr))
6296         {
6297             float quad1_modified[] =  {
6298                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6299                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6300                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6301                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6302             };
6303             float quad2_modified[] =  {
6304                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6305                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6306                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6307                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6308             };
6309
6310             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6311             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6312
6313             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6314             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6315             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6316             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6317
6318             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6319             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6320             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6321             if(i == 3 || i == 2) {
6322                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6323             } else if(i == 1) {
6324                 /* Succeeds or fails, depending on SW or HW vertex processing */
6325                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6326             }
6327
6328             hr = IDirect3DDevice9_EndScene(device);
6329             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6330         }
6331
6332         color = getPixelColor(device, 480, 350);
6333         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6334          * as well.
6335          *
6336          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6337          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6338          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6339          * refrast's result.
6340          *
6341          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6342          */
6343         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6344            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6345
6346         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6347         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6348
6349         IDirect3DDevice9_SetVertexShader(device, NULL);
6350         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6351
6352         IDirect3DVertexShader9_Release(swapped_shader);
6353     }
6354
6355     for(i = 1; i <= 3; i++) {
6356         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6357         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6358         if(i == 3) {
6359             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6360             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6361             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6362             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6363         } else if(i == 2){
6364             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6365             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6366             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6367             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6368         } else if(i == 1) {
6369             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6370             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6371             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6372             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6373         }
6374
6375         hr = IDirect3DDevice9_BeginScene(device);
6376         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6377         if(SUCCEEDED(hr))
6378         {
6379             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6380             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6381             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6382             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6383             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6384             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6385
6386             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6387             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6388
6389             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6390             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6391             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6392             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6393             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6394             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6395
6396             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6397             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6398             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6399             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6400             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6401             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6402
6403             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6404             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6405             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6406             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6407
6408             hr = IDirect3DDevice9_EndScene(device);
6409             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6410         }
6411         IDirect3DDevice9_SetVertexShader(device, NULL);
6412         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6413
6414         color = getPixelColor(device, 160, 360);
6415         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6416            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6417         color = getPixelColor(device, 480, 360);
6418         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6419            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6420         color = getPixelColor(device, 160, 120);
6421         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6422            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6423         color = getPixelColor(device, 480, 160);
6424         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6425            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6426
6427         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6428         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6429
6430         IDirect3DVertexShader9_Release(texcoord_color_shader);
6431         IDirect3DVertexShader9_Release(color_color_shader);
6432     }
6433
6434     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6435     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6436     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6437     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6438
6439     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6440     IDirect3DVertexDeclaration9_Release(decl_color_color);
6441     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6442     IDirect3DVertexDeclaration9_Release(decl_color_float);
6443 }
6444
6445 static void srgbtexture_test(IDirect3DDevice9 *device)
6446 {
6447     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6448      * texture stage state to render a quad using that texture.  The resulting
6449      * color components should be 0x36 (~ 0.21), per this formula:
6450      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6451      * This is true where srgb_color > 0.04045.
6452      */
6453     IDirect3D9 *d3d = NULL;
6454     HRESULT hr;
6455     LPDIRECT3DTEXTURE9 texture = NULL;
6456     LPDIRECT3DSURFACE9 surface = NULL;
6457     D3DLOCKED_RECT lr;
6458     DWORD color;
6459     float quad[] = {
6460         -1.0,       1.0,       0.0,     0.0,    0.0,
6461          1.0,       1.0,       0.0,     1.0,    0.0,
6462         -1.0,      -1.0,       0.0,     0.0,    1.0,
6463          1.0,      -1.0,       0.0,     1.0,    1.0,
6464     };
6465
6466
6467     memset(&lr, 0, sizeof(lr));
6468     IDirect3DDevice9_GetDirect3D(device, &d3d);
6469     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6470                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6471                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6472         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6473         goto out;
6474     }
6475
6476     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6477                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6478                                         &texture, NULL);
6479     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6480     if(!texture) {
6481         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6482         goto out;
6483     }
6484     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6485     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6486
6487     fill_surface(surface, 0xff7f7f7f);
6488     IDirect3DSurface9_Release(surface);
6489
6490     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6491     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6492     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6493     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6494
6495     hr = IDirect3DDevice9_BeginScene(device);
6496     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6497     if(SUCCEEDED(hr))
6498     {
6499         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6500         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6501
6502         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6503         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6504
6505
6506         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6507         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6508
6509         hr = IDirect3DDevice9_EndScene(device);
6510         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6511     }
6512
6513     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6514     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6515     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6516     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6517
6518     color = getPixelColor(device, 320, 240);
6519     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6520
6521     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6522     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6523
6524 out:
6525     if(texture) IDirect3DTexture9_Release(texture);
6526     IDirect3D9_Release(d3d);
6527 }
6528
6529 static void shademode_test(IDirect3DDevice9 *device)
6530 {
6531     /* Render a quad and try all of the different fixed function shading models. */
6532     HRESULT hr;
6533     DWORD color0, color1;
6534     DWORD color0_gouraud = 0, color1_gouraud = 0;
6535     DWORD shademode = D3DSHADE_FLAT;
6536     DWORD primtype = D3DPT_TRIANGLESTRIP;
6537     LPVOID data = NULL;
6538     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6539     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6540     UINT i, j;
6541     struct vertex quad_strip[] =
6542     {
6543         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6544         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6545         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6546         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6547     };
6548     struct vertex quad_list[] =
6549     {
6550         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6551         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6552         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6553
6554         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6555         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6556         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6557     };
6558
6559     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6560                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6561     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6562     if (FAILED(hr)) goto bail;
6563
6564     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6565                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6566     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6567     if (FAILED(hr)) goto bail;
6568
6569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6570     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6571
6572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6574
6575     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6576     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6577     memcpy(data, quad_strip, sizeof(quad_strip));
6578     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6579     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6580
6581     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6582     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6583     memcpy(data, quad_list, sizeof(quad_list));
6584     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6585     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6586
6587     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6588      * the color fixups we have to do for FLAT shading will be dependent on that. */
6589     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6590     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6591
6592     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6593     for (j=0; j<2; j++) {
6594
6595         /* Inner loop just changes the D3DRS_SHADEMODE */
6596         for (i=0; i<3; i++) {
6597             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6598             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6599
6600             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6601             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6602
6603             hr = IDirect3DDevice9_BeginScene(device);
6604             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6605             if(SUCCEEDED(hr))
6606             {
6607                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6608                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6609
6610                 hr = IDirect3DDevice9_EndScene(device);
6611                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6612             }
6613
6614             /* Sample two spots from the output */
6615             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6616             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6617             switch(shademode) {
6618                 case D3DSHADE_FLAT:
6619                     /* Should take the color of the first vertex of each triangle */
6620                     if (0)
6621                     {
6622                         /* This test depends on EXT_provoking_vertex being
6623                          * available. This extension is currently (20090810)
6624                          * not common enough to let the test fail if it isn't
6625                          * present. */
6626                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6627                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6628                     }
6629                     shademode = D3DSHADE_GOURAUD;
6630                     break;
6631                 case D3DSHADE_GOURAUD:
6632                     /* Should be an interpolated blend */
6633
6634                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6635                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6636                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6637                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6638
6639                     color0_gouraud = color0;
6640                     color1_gouraud = color1;
6641
6642                     shademode = D3DSHADE_PHONG;
6643                     break;
6644                 case D3DSHADE_PHONG:
6645                     /* Should be the same as GOURAUD, since no hardware implements this */
6646                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6647                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6648                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6649                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6650
6651                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6652                             color0_gouraud, color0);
6653                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6654                             color1_gouraud, color1);
6655                     break;
6656             }
6657         }
6658
6659         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6660         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6661
6662         /* Now, do it all over again with a TRIANGLELIST */
6663         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6664         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6665         primtype = D3DPT_TRIANGLELIST;
6666         shademode = D3DSHADE_FLAT;
6667     }
6668
6669 bail:
6670     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6671     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6672     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6673     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6674
6675     if (vb_strip)
6676         IDirect3DVertexBuffer9_Release(vb_strip);
6677     if (vb_list)
6678         IDirect3DVertexBuffer9_Release(vb_list);
6679 }
6680
6681 static void alpha_test(IDirect3DDevice9 *device)
6682 {
6683     HRESULT hr;
6684     IDirect3DTexture9 *offscreenTexture;
6685     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6686     DWORD color;
6687
6688     struct vertex quad1[] =
6689     {
6690         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6691         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6692         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6693         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6694     };
6695     struct vertex quad2[] =
6696     {
6697         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6698         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6699         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6700         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6701     };
6702     static const float composite_quad[][5] = {
6703         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6704         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6705         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6706         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6707     };
6708
6709     /* Clear the render target with alpha = 0.5 */
6710     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6711     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6712
6713     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6714     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6715
6716     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6717     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6718     if(!backbuffer) {
6719         goto out;
6720     }
6721
6722     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6723     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6724     if(!offscreen) {
6725         goto out;
6726     }
6727
6728     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6729     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6730
6731     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6732     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6733     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6734     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6735     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6736     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6737     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6738     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6739     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6740     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6741
6742     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6743     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6744     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6745
6746         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6747         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6748         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6749         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6750         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6751         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6752         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6753
6754         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6755         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6756         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6757         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6758         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6759         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6760
6761         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6762          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6763          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6764         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6765         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6766         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6767         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6768
6769         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6770         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6771         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6772         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6773         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6774         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6775
6776         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6777         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6778         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6779         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6780         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6781         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6782
6783         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6784         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6785
6786         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6787          * Disable alpha blending for the final composition
6788          */
6789         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6790         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6791         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6792         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6793
6794         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6795         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6796         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6797         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6798         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6799         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6800
6801         hr = IDirect3DDevice9_EndScene(device);
6802         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6803     }
6804
6805     color = getPixelColor(device, 160, 360);
6806     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6807        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6808
6809     color = getPixelColor(device, 160, 120);
6810     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6811        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6812
6813     color = getPixelColor(device, 480, 360);
6814     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6815        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6816
6817     color = getPixelColor(device, 480, 120);
6818     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6819        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6820
6821     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6822
6823     out:
6824     /* restore things */
6825     if(backbuffer) {
6826         IDirect3DSurface9_Release(backbuffer);
6827     }
6828     if(offscreenTexture) {
6829         IDirect3DTexture9_Release(offscreenTexture);
6830     }
6831     if(offscreen) {
6832         IDirect3DSurface9_Release(offscreen);
6833     }
6834 }
6835
6836 struct vertex_shortcolor {
6837     float x, y, z;
6838     unsigned short r, g, b, a;
6839 };
6840 struct vertex_floatcolor {
6841     float x, y, z;
6842     float r, g, b, a;
6843 };
6844
6845 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6846 {
6847     HRESULT hr;
6848     BOOL s_ok, ub_ok, f_ok;
6849     DWORD color, size, i;
6850     void *data;
6851     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6852         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6853         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6854         D3DDECL_END()
6855     };
6856     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6857         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6858         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6859         D3DDECL_END()
6860     };
6861     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6862         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6863         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6864         D3DDECL_END()
6865     };
6866     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6867         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6868         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6869         D3DDECL_END()
6870     };
6871     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6872         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6873         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6874         D3DDECL_END()
6875     };
6876     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6877         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6878         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6879         D3DDECL_END()
6880     };
6881     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6882         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6883         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6884         D3DDECL_END()
6885     };
6886     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6887     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6888     IDirect3DVertexBuffer9 *vb, *vb2;
6889     struct vertex quad1[] =                             /* D3DCOLOR */
6890     {
6891         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6892         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6893         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6894         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6895     };
6896     struct vertex quad2[] =                             /* UBYTE4N */
6897     {
6898         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6899         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6900         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6901         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6902     };
6903     struct vertex_shortcolor quad3[] =                  /* short */
6904     {
6905         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6906         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6907         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6908         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6909     };
6910     struct vertex_floatcolor quad4[] =
6911     {
6912         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6913         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6914         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6915         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6916     };
6917     DWORD colors[] = {
6918         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6919         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6920         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6921         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6922         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6923         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6924         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6925         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6926         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6927         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6928         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6929         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6930         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6931         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6932         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6933         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6934     };
6935     float quads[] = {
6936         -1.0,   -1.0,     0.1,
6937         -1.0,    0.0,     0.1,
6938          0.0,   -1.0,     0.1,
6939          0.0,    0.0,     0.1,
6940
6941          0.0,   -1.0,     0.1,
6942          0.0,    0.0,     0.1,
6943          1.0,   -1.0,     0.1,
6944          1.0,    0.0,     0.1,
6945
6946          0.0,    0.0,     0.1,
6947          0.0,    1.0,     0.1,
6948          1.0,    0.0,     0.1,
6949          1.0,    1.0,     0.1,
6950
6951         -1.0,    0.0,     0.1,
6952         -1.0,    1.0,     0.1,
6953          0.0,    0.0,     0.1,
6954          0.0,    1.0,     0.1
6955     };
6956     struct tvertex quad_transformed[] = {
6957        {  90,    110,     0.1,      2.0,        0x00ffff00},
6958        { 570,    110,     0.1,      2.0,        0x00ffff00},
6959        {  90,    300,     0.1,      2.0,        0x00ffff00},
6960        { 570,    300,     0.1,      2.0,        0x00ffff00}
6961     };
6962     D3DCAPS9 caps;
6963
6964     memset(&caps, 0, sizeof(caps));
6965     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6966     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6967
6968     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6969     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6970
6971     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6972     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6973     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6974     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6975     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6976     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6977     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6978         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6979         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6980         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6981         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6982     } else {
6983         trace("D3DDTCAPS_UBYTE4N not supported\n");
6984         dcl_ubyte_2 = NULL;
6985         dcl_ubyte = NULL;
6986     }
6987     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6988     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6989     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6990     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6991
6992     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6993     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6994                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
6995     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6996
6997     hr = IDirect3DDevice9_BeginScene(device);
6998     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6999     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7000     if(SUCCEEDED(hr)) {
7001         if(dcl_color) {
7002             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7003             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7004             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7005             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7006         }
7007
7008         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7009          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7010          * using software vertex processing. Doh!
7011          */
7012         if(dcl_ubyte) {
7013             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7014             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7015             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7016             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7017             ub_ok = SUCCEEDED(hr);
7018         }
7019
7020         if(dcl_short) {
7021             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7022             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7024             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7025             s_ok = SUCCEEDED(hr);
7026         }
7027
7028         if(dcl_float) {
7029             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7030             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7031             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7032             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7033             f_ok = SUCCEEDED(hr);
7034         }
7035
7036         hr = IDirect3DDevice9_EndScene(device);
7037         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7038     }
7039
7040     if(dcl_short) {
7041         color = getPixelColor(device, 480, 360);
7042         ok(color == 0x000000ff || !s_ok,
7043            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7044     }
7045     if(dcl_ubyte) {
7046         color = getPixelColor(device, 160, 120);
7047         ok(color == 0x0000ffff || !ub_ok,
7048            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7049     }
7050     if(dcl_color) {
7051         color = getPixelColor(device, 160, 360);
7052         ok(color == 0x00ffff00,
7053            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7054     }
7055     if(dcl_float) {
7056         color = getPixelColor(device, 480, 120);
7057         ok(color == 0x00ff0000 || !f_ok,
7058            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7059     }
7060     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7061
7062     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7063      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7064      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7065      * whether the immediate mode code works
7066      */
7067     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7068     hr = IDirect3DDevice9_BeginScene(device);
7069     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7070     if(SUCCEEDED(hr)) {
7071         if(dcl_color) {
7072             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7073             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7074             memcpy(data, quad1, sizeof(quad1));
7075             hr = IDirect3DVertexBuffer9_Unlock(vb);
7076             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7077             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7078             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7079             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7080             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7081             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7082             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7083         }
7084
7085         if(dcl_ubyte) {
7086             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7087             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7088             memcpy(data, quad2, sizeof(quad2));
7089             hr = IDirect3DVertexBuffer9_Unlock(vb);
7090             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7091             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7092             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7093             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7094             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7095             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7096             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7097                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7098             ub_ok = SUCCEEDED(hr);
7099         }
7100
7101         if(dcl_short) {
7102             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7103             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7104             memcpy(data, quad3, sizeof(quad3));
7105             hr = IDirect3DVertexBuffer9_Unlock(vb);
7106             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7107             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7108             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7109             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7110             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7111             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7112             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7113                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7114             s_ok = SUCCEEDED(hr);
7115         }
7116
7117         if(dcl_float) {
7118             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7119             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7120             memcpy(data, quad4, sizeof(quad4));
7121             hr = IDirect3DVertexBuffer9_Unlock(vb);
7122             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7123             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7124             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7125             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7126             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7127             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7128             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7129                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7130             f_ok = SUCCEEDED(hr);
7131         }
7132
7133         hr = IDirect3DDevice9_EndScene(device);
7134         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7135     }
7136
7137     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7138     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7139     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7140     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7141
7142     if(dcl_short) {
7143         color = getPixelColor(device, 480, 360);
7144         ok(color == 0x000000ff || !s_ok,
7145            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7146     }
7147     if(dcl_ubyte) {
7148         color = getPixelColor(device, 160, 120);
7149         ok(color == 0x0000ffff || !ub_ok,
7150            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7151     }
7152     if(dcl_color) {
7153         color = getPixelColor(device, 160, 360);
7154         ok(color == 0x00ffff00,
7155            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7156     }
7157     if(dcl_float) {
7158         color = getPixelColor(device, 480, 120);
7159         ok(color == 0x00ff0000 || !f_ok,
7160            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7161     }
7162     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7163
7164     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7165     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7166
7167     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7168     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7169     memcpy(data, quad_transformed, sizeof(quad_transformed));
7170     hr = IDirect3DVertexBuffer9_Unlock(vb);
7171     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7172
7173     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7174     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7175
7176     hr = IDirect3DDevice9_BeginScene(device);
7177     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7178     if(SUCCEEDED(hr)) {
7179         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7180         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7181         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7182         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7183
7184         hr = IDirect3DDevice9_EndScene(device);
7185         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7186     }
7187
7188     color = getPixelColor(device, 88, 108);
7189     ok(color == 0x000000ff,
7190        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7191     color = getPixelColor(device, 92, 108);
7192     ok(color == 0x000000ff,
7193        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7194     color = getPixelColor(device, 88, 112);
7195     ok(color == 0x000000ff,
7196        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7197     color = getPixelColor(device, 92, 112);
7198     ok(color == 0x00ffff00,
7199        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7200
7201     color = getPixelColor(device, 568, 108);
7202     ok(color == 0x000000ff,
7203        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7204     color = getPixelColor(device, 572, 108);
7205     ok(color == 0x000000ff,
7206        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7207     color = getPixelColor(device, 568, 112);
7208     ok(color == 0x00ffff00,
7209        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7210     color = getPixelColor(device, 572, 112);
7211     ok(color == 0x000000ff,
7212        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7213
7214     color = getPixelColor(device, 88, 298);
7215     ok(color == 0x000000ff,
7216        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7217     color = getPixelColor(device, 92, 298);
7218     ok(color == 0x00ffff00,
7219        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7220     color = getPixelColor(device, 88, 302);
7221     ok(color == 0x000000ff,
7222        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7223     color = getPixelColor(device, 92, 302);
7224     ok(color == 0x000000ff,
7225        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7226
7227     color = getPixelColor(device, 568, 298);
7228     ok(color == 0x00ffff00,
7229        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7230     color = getPixelColor(device, 572, 298);
7231     ok(color == 0x000000ff,
7232        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7233     color = getPixelColor(device, 568, 302);
7234     ok(color == 0x000000ff,
7235        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7236     color = getPixelColor(device, 572, 302);
7237     ok(color == 0x000000ff,
7238        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7239
7240     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7241
7242     /* This test is pointless without those two declarations: */
7243     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7244         skip("color-ubyte switching test declarations aren't supported\n");
7245         goto out;
7246     }
7247
7248     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7249     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7250     memcpy(data, quads, sizeof(quads));
7251     hr = IDirect3DVertexBuffer9_Unlock(vb);
7252     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7253     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7254                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7255     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7256     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7257     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7258     memcpy(data, colors, sizeof(colors));
7259     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7260     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7261
7262     for(i = 0; i < 2; i++) {
7263         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7264         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7265
7266         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7267         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7268         if(i == 0) {
7269             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7270         } else {
7271             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7272         }
7273         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7274
7275         hr = IDirect3DDevice9_BeginScene(device);
7276         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7277         ub_ok = FALSE;
7278         if(SUCCEEDED(hr)) {
7279             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7280             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7281             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7282             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7283                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7284             ub_ok = SUCCEEDED(hr);
7285
7286             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7287             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7288             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7289             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7290
7291             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7292             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7293             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7294             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7295                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7296             ub_ok = (SUCCEEDED(hr) && ub_ok);
7297
7298             hr = IDirect3DDevice9_EndScene(device);
7299             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7300         }
7301
7302         if(i == 0) {
7303             color = getPixelColor(device, 480, 360);
7304             ok(color == 0x00ff0000,
7305                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7306             color = getPixelColor(device, 160, 120);
7307             ok(color == 0x00ffffff,
7308                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7309             color = getPixelColor(device, 160, 360);
7310             ok(color == 0x000000ff || !ub_ok,
7311                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7312             color = getPixelColor(device, 480, 120);
7313             ok(color == 0x000000ff || !ub_ok,
7314                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7315         } else {
7316             color = getPixelColor(device, 480, 360);
7317             ok(color == 0x000000ff,
7318                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7319             color = getPixelColor(device, 160, 120);
7320             ok(color == 0x00ffffff,
7321                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7322             color = getPixelColor(device, 160, 360);
7323             ok(color == 0x00ff0000 || !ub_ok,
7324                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7325             color = getPixelColor(device, 480, 120);
7326             ok(color == 0x00ff0000 || !ub_ok,
7327                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7328         }
7329         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7330     }
7331
7332     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7333     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7334     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7335     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7336     IDirect3DVertexBuffer9_Release(vb2);
7337
7338     out:
7339     IDirect3DVertexBuffer9_Release(vb);
7340     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7341     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7342     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7343     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7344     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7345     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7346     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7347 }
7348
7349 struct vertex_float16color {
7350     float x, y, z;
7351     DWORD c1, c2;
7352 };
7353
7354 static void test_vshader_float16(IDirect3DDevice9 *device)
7355 {
7356     HRESULT hr;
7357     DWORD color;
7358     void *data;
7359     static const D3DVERTEXELEMENT9 decl_elements[] = {
7360         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7361         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7362         D3DDECL_END()
7363     };
7364     IDirect3DVertexDeclaration9 *vdecl = NULL;
7365     IDirect3DVertexBuffer9 *buffer = NULL;
7366     IDirect3DVertexShader9 *shader;
7367     DWORD shader_code[] = {
7368         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7369         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7370         0x90e40001, 0x0000ffff
7371     };
7372     struct vertex_float16color quad[] = {
7373         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7374         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7375         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7376         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7377
7378         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7379         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7380         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7381         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7382
7383         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7384         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7385         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7386         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7387
7388         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7389         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7390         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7391         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7392     };
7393
7394     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7395     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7396
7397     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7398     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7399     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7400     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7401     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7402     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7403
7404     hr = IDirect3DDevice9_BeginScene(device);
7405     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7406     if(SUCCEEDED(hr)) {
7407         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7408         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7410         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7412         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7413         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7414         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7415         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7416         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7417
7418         hr = IDirect3DDevice9_EndScene(device);
7419         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7420     }
7421     color = getPixelColor(device, 480, 360);
7422     ok(color == 0x00ff0000,
7423        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7424     color = getPixelColor(device, 160, 120);
7425     ok(color == 0x00000000,
7426        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7427     color = getPixelColor(device, 160, 360);
7428     ok(color == 0x0000ff00,
7429        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7430     color = getPixelColor(device, 480, 120);
7431     ok(color == 0x000000ff,
7432        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7433     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7434
7435     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7436     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7437
7438     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7439                                              D3DPOOL_MANAGED, &buffer, NULL);
7440     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7441     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7442     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7443     memcpy(data, quad, sizeof(quad));
7444     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7445     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7446     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7447     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7448
7449     hr = IDirect3DDevice9_BeginScene(device);
7450     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7451     if(SUCCEEDED(hr)) {
7452             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7453             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7454             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7455             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7456             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7457             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7458             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7459             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7460
7461             hr = IDirect3DDevice9_EndScene(device);
7462             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7463     }
7464
7465     color = getPixelColor(device, 480, 360);
7466     ok(color == 0x00ff0000,
7467        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7468     color = getPixelColor(device, 160, 120);
7469     ok(color == 0x00000000,
7470        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7471     color = getPixelColor(device, 160, 360);
7472     ok(color == 0x0000ff00,
7473        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7474     color = getPixelColor(device, 480, 120);
7475     ok(color == 0x000000ff,
7476        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7477     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7478
7479     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7480     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7481     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7482     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7483     IDirect3DDevice9_SetVertexShader(device, NULL);
7484     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7485
7486     IDirect3DVertexDeclaration9_Release(vdecl);
7487     IDirect3DVertexShader9_Release(shader);
7488     IDirect3DVertexBuffer9_Release(buffer);
7489 }
7490
7491 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7492 {
7493     D3DCAPS9 caps;
7494     IDirect3DTexture9 *texture;
7495     HRESULT hr;
7496     D3DLOCKED_RECT rect;
7497     unsigned int x, y;
7498     DWORD *dst, color;
7499     const float quad[] = {
7500         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7501          1.0,   -1.0,   0.1,    1.2,   -0.2,
7502         -1.0,    1.0,   0.1,   -0.2,    1.2,
7503          1.0,    1.0,   0.1,    1.2,    1.2
7504     };
7505     memset(&caps, 0, sizeof(caps));
7506
7507     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7508     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7509     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7510         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7511         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7512            "Card has conditional NP2 support without power of two restriction set\n");
7513         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7514         return;
7515     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7516         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7517         return;
7518     }
7519
7520     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7521     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7522
7523     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7524     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7525
7526     memset(&rect, 0, sizeof(rect));
7527     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7528     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7529     for(y = 0; y < 10; y++) {
7530         for(x = 0; x < 10; x++) {
7531             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7532             if(x == 0 || x == 9 || y == 0 || y == 9) {
7533                 *dst = 0x00ff0000;
7534             } else {
7535                 *dst = 0x000000ff;
7536             }
7537         }
7538     }
7539     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7540     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7541
7542     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7543     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7544     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7545     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7546     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7547     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7548     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7549     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7550
7551     hr = IDirect3DDevice9_BeginScene(device);
7552     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7553     if(SUCCEEDED(hr)) {
7554         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7555         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7556
7557         hr = IDirect3DDevice9_EndScene(device);
7558         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7559     }
7560
7561     color = getPixelColor(device,    1,  1);
7562     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7563     color = getPixelColor(device, 639, 479);
7564     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7565
7566     color = getPixelColor(device, 135, 101);
7567     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7568     color = getPixelColor(device, 140, 101);
7569     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7570     color = getPixelColor(device, 135, 105);
7571     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7572     color = getPixelColor(device, 140, 105);
7573     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7574
7575     color = getPixelColor(device, 135, 376);
7576     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7577     color = getPixelColor(device, 140, 376);
7578     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7579     color = getPixelColor(device, 135, 379);
7580     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7581     color = getPixelColor(device, 140, 379);
7582     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7583
7584     color = getPixelColor(device, 500, 101);
7585     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7586     color = getPixelColor(device, 504, 101);
7587     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7588     color = getPixelColor(device, 500, 105);
7589     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7590     color = getPixelColor(device, 504, 105);
7591     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7592
7593     color = getPixelColor(device, 500, 376);
7594     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7595     color = getPixelColor(device, 504, 376);
7596     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7597     color = getPixelColor(device, 500, 380);
7598     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7599     color = getPixelColor(device, 504, 380);
7600     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7601
7602     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7603
7604     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7605     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7606     IDirect3DTexture9_Release(texture);
7607 }
7608
7609 static void vFace_register_test(IDirect3DDevice9 *device)
7610 {
7611     HRESULT hr;
7612     DWORD color;
7613     const DWORD shader_code[] = {
7614         0xffff0300,                                                             /* ps_3_0                     */
7615         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7616         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7617         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7618         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7619         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7620         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7621         0x0000ffff                                                              /* END                        */
7622     };
7623     const DWORD vshader_code[] = {
7624         0xfffe0300,                                                             /* vs_3_0               */
7625         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7626         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7627         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7628         0x0000ffff                                                              /* end                  */
7629     };
7630     IDirect3DPixelShader9 *shader;
7631     IDirect3DVertexShader9 *vshader;
7632     IDirect3DTexture9 *texture;
7633     IDirect3DSurface9 *surface, *backbuffer;
7634     const float quad[] = {
7635         -1.0,   -1.0,   0.1,
7636          1.0,   -1.0,   0.1,
7637         -1.0,    0.0,   0.1,
7638
7639          1.0,   -1.0,   0.1,
7640          1.0,    0.0,   0.1,
7641         -1.0,    0.0,   0.1,
7642
7643         -1.0,    0.0,   0.1,
7644         -1.0,    1.0,   0.1,
7645          1.0,    0.0,   0.1,
7646
7647          1.0,    0.0,   0.1,
7648         -1.0,    1.0,   0.1,
7649          1.0,    1.0,   0.1,
7650     };
7651     const float blit[] = {
7652          0.0,   -1.0,   0.1,    0.0,    0.0,
7653          1.0,   -1.0,   0.1,    1.0,    0.0,
7654          0.0,    1.0,   0.1,    0.0,    1.0,
7655          1.0,    1.0,   0.1,    1.0,    1.0,
7656     };
7657
7658     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7659     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7660     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7661     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7662     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7663     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7664     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7665     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7666     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7667     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7668     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7669     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7670     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7671     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7672     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7673     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7674
7675     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7676     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7677
7678     hr = IDirect3DDevice9_BeginScene(device);
7679     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7680     if(SUCCEEDED(hr)) {
7681         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7682         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7683         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7684         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7685         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7686         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7687         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7688         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7689         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7690         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7691         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7692
7693         /* Blit the texture onto the back buffer to make it visible */
7694         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7695         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7696         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7697         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7698         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7699         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7700         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7701         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7702         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7703         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7704         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7705         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7706
7707         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7708         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7709
7710         hr = IDirect3DDevice9_EndScene(device);
7711         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7712     }
7713
7714     color = getPixelColor(device, 160, 360);
7715     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7716     color = getPixelColor(device, 160, 120);
7717     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7718     color = getPixelColor(device, 480, 360);
7719     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7720     color = getPixelColor(device, 480, 120);
7721     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7722     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7723
7724     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7725     IDirect3DDevice9_SetTexture(device, 0, NULL);
7726     IDirect3DPixelShader9_Release(shader);
7727     IDirect3DVertexShader9_Release(vshader);
7728     IDirect3DSurface9_Release(surface);
7729     IDirect3DSurface9_Release(backbuffer);
7730     IDirect3DTexture9_Release(texture);
7731 }
7732
7733 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7734 {
7735     HRESULT hr;
7736     DWORD color;
7737     int i;
7738     D3DCAPS9 caps;
7739     BOOL L6V5U5_supported = FALSE;
7740     IDirect3DTexture9 *tex1, *tex2;
7741     D3DLOCKED_RECT locked_rect;
7742
7743     static const float quad[][7] = {
7744         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7745         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7746         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7747         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7748     };
7749
7750     static const D3DVERTEXELEMENT9 decl_elements[] = {
7751         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7752         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7753         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7754         D3DDECL_END()
7755     };
7756
7757     /* use asymmetric matrix to test loading */
7758     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7759     float scale, offset;
7760
7761     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7762     IDirect3DTexture9           *texture            = NULL;
7763
7764     memset(&caps, 0, sizeof(caps));
7765     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7766     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7767     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7768         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7769         return;
7770     } else {
7771         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7772          * They report that it is not supported, but after that bump mapping works properly. So just test
7773          * if the format is generally supported, and check the BUMPENVMAP flag
7774          */
7775         IDirect3D9 *d3d9;
7776
7777         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7778         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7779                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7780         L6V5U5_supported = SUCCEEDED(hr);
7781         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7782                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7783         IDirect3D9_Release(d3d9);
7784         if(FAILED(hr)) {
7785             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7786             return;
7787         }
7788     }
7789
7790     /* Generate the textures */
7791     generate_bumpmap_textures(device);
7792
7793     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7794     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7795     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7796     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7797     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7798     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7800     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7801
7802     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7803     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7804     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7805     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7807     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808
7809     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7810     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7811     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7812     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7813     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7814     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7815
7816     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7817     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7818
7819     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7820     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7821
7822     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7823     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7824
7825
7826     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7827     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7828     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7829     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7830
7831     hr = IDirect3DDevice9_BeginScene(device);
7832     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7833
7834     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7835     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7836
7837     hr = IDirect3DDevice9_EndScene(device);
7838     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7839
7840     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7841      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7842      * But since testing the color match is not the purpose of the test don't be too picky
7843      */
7844     color = getPixelColor(device, 320-32, 240);
7845     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7846     color = getPixelColor(device, 320+32, 240);
7847     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7848     color = getPixelColor(device, 320, 240-32);
7849     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7850     color = getPixelColor(device, 320, 240+32);
7851     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7852     color = getPixelColor(device, 320, 240);
7853     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7854     color = getPixelColor(device, 320+32, 240+32);
7855     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7856     color = getPixelColor(device, 320-32, 240+32);
7857     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7858     color = getPixelColor(device, 320+32, 240-32);
7859     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7860     color = getPixelColor(device, 320-32, 240-32);
7861     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7862     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7863     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7864
7865     for(i = 0; i < 2; i++) {
7866         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7867         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7868         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7869         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7870         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7871         IDirect3DTexture9_Release(texture); /* To destroy it */
7872     }
7873
7874     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7875         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7876         goto cleanup;
7877     }
7878     if(L6V5U5_supported == FALSE) {
7879         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7880         goto cleanup;
7881     }
7882
7883     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7884     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7885     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7886      * would only make this test more complicated
7887      */
7888     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7889     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7890     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7891     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7892
7893     memset(&locked_rect, 0, sizeof(locked_rect));
7894     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7895     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7896     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7897     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7898     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7899
7900     memset(&locked_rect, 0, sizeof(locked_rect));
7901     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7902     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7903     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7904     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7905     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7906
7907     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7908     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7909     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7910     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7911
7912     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7913     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7914     scale = 2.0;
7915     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7916     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7917     offset = 0.1;
7918     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7919     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7920
7921     hr = IDirect3DDevice9_BeginScene(device);
7922     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7923     if(SUCCEEDED(hr)) {
7924         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7925         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7926         hr = IDirect3DDevice9_EndScene(device);
7927         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7928     }
7929
7930     color = getPixelColor(device, 320, 240);
7931     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7932      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7933      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7934      */
7935     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7936     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7937     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7938
7939     /* Check a result scale factor > 1.0 */
7940     scale = 10;
7941     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7942     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7943     offset = 10;
7944     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7945     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7946
7947     hr = IDirect3DDevice9_BeginScene(device);
7948     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7949     if(SUCCEEDED(hr)) {
7950         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7951         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7952         hr = IDirect3DDevice9_EndScene(device);
7953         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7954     }
7955     color = getPixelColor(device, 320, 240);
7956     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7957     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7958     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7959
7960     /* Check clamping in the scale factor calculation */
7961     scale = 1000;
7962     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7963     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7964     offset = -1;
7965     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7966     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7967
7968     hr = IDirect3DDevice9_BeginScene(device);
7969     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7970     if(SUCCEEDED(hr)) {
7971         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7972         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7973         hr = IDirect3DDevice9_EndScene(device);
7974         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7975     }
7976     color = getPixelColor(device, 320, 240);
7977     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7978     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7979     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7980
7981     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7982     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7983     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7984     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7985
7986     IDirect3DTexture9_Release(tex1);
7987     IDirect3DTexture9_Release(tex2);
7988
7989 cleanup:
7990     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7991     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7992     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7993     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7994
7995     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7996     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7997     IDirect3DVertexDeclaration9_Release(vertex_declaration);
7998 }
7999
8000 static void stencil_cull_test(IDirect3DDevice9 *device) {
8001     HRESULT hr;
8002     IDirect3DSurface9 *depthstencil = NULL;
8003     D3DSURFACE_DESC desc;
8004     float quad1[] = {
8005         -1.0,   -1.0,   0.1,
8006          0.0,   -1.0,   0.1,
8007         -1.0,    0.0,   0.1,
8008          0.0,    0.0,   0.1,
8009     };
8010     float quad2[] = {
8011          0.0,   -1.0,   0.1,
8012          1.0,   -1.0,   0.1,
8013          0.0,    0.0,   0.1,
8014          1.0,    0.0,   0.1,
8015     };
8016     float quad3[] = {
8017         0.0,    0.0,   0.1,
8018         1.0,    0.0,   0.1,
8019         0.0,    1.0,   0.1,
8020         1.0,    1.0,   0.1,
8021     };
8022     float quad4[] = {
8023         -1.0,    0.0,   0.1,
8024          0.0,    0.0,   0.1,
8025         -1.0,    1.0,   0.1,
8026          0.0,    1.0,   0.1,
8027     };
8028     struct vertex painter[] = {
8029        {-1.0,   -1.0,   0.0,    0x00000000},
8030        { 1.0,   -1.0,   0.0,    0x00000000},
8031        {-1.0,    1.0,   0.0,    0x00000000},
8032        { 1.0,    1.0,   0.0,    0x00000000},
8033     };
8034     WORD indices_cw[]  = {0, 1, 3};
8035     WORD indices_ccw[] = {0, 2, 3};
8036     unsigned int i;
8037     DWORD color;
8038
8039     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8040     if(depthstencil == NULL) {
8041         skip("No depth stencil buffer\n");
8042         return;
8043     }
8044     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8045     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8046     IDirect3DSurface9_Release(depthstencil);
8047     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8048         skip("No 4 or 8 bit stencil surface\n");
8049         return;
8050     }
8051
8052     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8053     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8054     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8055
8056     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8057     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8058     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8059     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8060     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8061     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8062     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8063     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8064
8065     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8066     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8067     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8068     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8069     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8070     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8071
8072     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8073     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8074     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8075     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8076
8077     /* First pass: Fill the stencil buffer with some values... */
8078     hr = IDirect3DDevice9_BeginScene(device);
8079     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8080     if(SUCCEEDED(hr))
8081     {
8082         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8083         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8084         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8085                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8086         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8087         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8088                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8089         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8090
8091         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8092         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8094         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8095         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8096                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8097         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8098         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8099                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8100         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8101
8102         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8103         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8104         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8105                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8106         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8107         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8108                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8109         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8110
8111         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8112         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8113         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8114                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8115         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8116         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8117                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8118         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8119
8120         hr = IDirect3DDevice9_EndScene(device);
8121         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8122     }
8123
8124     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8125     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8126     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8127     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8128     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8129     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8130     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8131     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8132     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8133     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8134     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8135     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8136     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8137
8138     /* 2nd pass: Make the stencil values visible */
8139     hr = IDirect3DDevice9_BeginScene(device);
8140     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8141     if(SUCCEEDED(hr))
8142     {
8143         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8144         for(i = 0; i < 16; i++) {
8145             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8146             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8147
8148             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8149             painter[1].diffuse = (i * 16);
8150             painter[2].diffuse = (i * 16);
8151             painter[3].diffuse = (i * 16);
8152             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8153             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8154         }
8155         hr = IDirect3DDevice9_EndScene(device);
8156         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8157     }
8158
8159     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8160     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8161
8162     color = getPixelColor(device, 160, 420);
8163     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8164     color = getPixelColor(device, 160, 300);
8165     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8166
8167     color = getPixelColor(device, 480, 420);
8168     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8169     color = getPixelColor(device, 480, 300);
8170     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8171
8172     color = getPixelColor(device, 160, 180);
8173     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8174     color = getPixelColor(device, 160, 60);
8175     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8176
8177     color = getPixelColor(device, 480, 180);
8178     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8179     color = getPixelColor(device, 480, 60);
8180     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8181
8182     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8183     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8184 }
8185
8186 static void vpos_register_test(IDirect3DDevice9 *device)
8187 {
8188     HRESULT hr;
8189     DWORD color;
8190     const DWORD shader_code[] = {
8191     0xffff0300,                                                             /* ps_3_0                     */
8192     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8193     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8194     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8195     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8196     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8197     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8198     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8199     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8200     0x0000ffff                                                              /* end                        */
8201     };
8202     const DWORD shader_frac_code[] = {
8203     0xffff0300,                                                             /* ps_3_0                     */
8204     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8205     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8206     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8207     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8208     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8209     0x0000ffff                                                              /* end                        */
8210     };
8211     const DWORD vshader_code[] = {
8212         0xfffe0300,                                                             /* vs_3_0               */
8213         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8214         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8215         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8216         0x0000ffff                                                              /* end                  */
8217     };
8218     IDirect3DVertexShader9 *vshader;
8219     IDirect3DPixelShader9 *shader, *shader_frac;
8220     IDirect3DSurface9 *surface = NULL, *backbuffer;
8221     const float quad[] = {
8222         -1.0,   -1.0,   0.1,    0.0,    0.0,
8223          1.0,   -1.0,   0.1,    1.0,    0.0,
8224         -1.0,    1.0,   0.1,    0.0,    1.0,
8225          1.0,    1.0,   0.1,    1.0,    1.0,
8226     };
8227     D3DLOCKED_RECT lr;
8228     float constant[4] = {1.0, 0.0, 320, 240};
8229     DWORD *pos;
8230
8231     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8232     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8233     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8234     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8235     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8236     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8237     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8238     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8239     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8240     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8241     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8242     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8243     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8244     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8245     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8246     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8247
8248     hr = IDirect3DDevice9_BeginScene(device);
8249     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8250     if(SUCCEEDED(hr)) {
8251         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8252         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8253         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8254         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8255         hr = IDirect3DDevice9_EndScene(device);
8256         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8257     }
8258
8259     /* This has to be pixel exact */
8260     color = getPixelColor(device, 319, 239);
8261     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8262     color = getPixelColor(device, 320, 239);
8263     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8264     color = getPixelColor(device, 319, 240);
8265     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8266     color = getPixelColor(device, 320, 240);
8267     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8268     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8269
8270     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8271                                              &surface, NULL);
8272     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8273     hr = IDirect3DDevice9_BeginScene(device);
8274     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8275     if(SUCCEEDED(hr)) {
8276         constant[2] = 16; constant[3] = 16;
8277         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8278         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8279         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8280         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8281         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8282         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8283         hr = IDirect3DDevice9_EndScene(device);
8284         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8285     }
8286     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8287     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8288
8289     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8290     color = *pos & 0x00ffffff;
8291     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8292     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8293     color = *pos & 0x00ffffff;
8294     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8295     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8296     color = *pos & 0x00ffffff;
8297     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8298     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8299     color = *pos & 0x00ffffff;
8300     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8301
8302     hr = IDirect3DSurface9_UnlockRect(surface);
8303     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8304
8305     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8306      * have full control over the multisampling setting inside this test
8307      */
8308     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8309     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8310     hr = IDirect3DDevice9_BeginScene(device);
8311     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8312     if(SUCCEEDED(hr)) {
8313         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8314         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8316         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8317         hr = IDirect3DDevice9_EndScene(device);
8318         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8319     }
8320     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8321     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8322
8323     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8324     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8325
8326     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8327     color = *pos & 0x00ffffff;
8328     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8329
8330     hr = IDirect3DSurface9_UnlockRect(surface);
8331     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8332
8333     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8334     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8335     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8336     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8337     IDirect3DPixelShader9_Release(shader);
8338     IDirect3DPixelShader9_Release(shader_frac);
8339     IDirect3DVertexShader9_Release(vshader);
8340     if(surface) IDirect3DSurface9_Release(surface);
8341     IDirect3DSurface9_Release(backbuffer);
8342 }
8343
8344 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8345 {
8346     D3DCOLOR color;
8347
8348     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8349     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8350     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8351     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8352     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8353
8354     ++r;
8355     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8356     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8357     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8358     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8359     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8360
8361     return TRUE;
8362 }
8363
8364 static void pointsize_test(IDirect3DDevice9 *device)
8365 {
8366     HRESULT hr;
8367     D3DCAPS9 caps;
8368     D3DMATRIX matrix;
8369     D3DMATRIX identity;
8370     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8371     DWORD color;
8372     IDirect3DSurface9 *rt, *backbuffer;
8373     IDirect3DTexture9 *tex1, *tex2;
8374     RECT rect = {0, 0, 128, 128};
8375     D3DLOCKED_RECT lr;
8376     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8377                                 0x00000000, 0x00000000};
8378     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8379                                 0x00000000, 0x0000ff00};
8380
8381     const float vertices[] = {
8382         64,     64,     0.1,
8383         128,    64,     0.1,
8384         192,    64,     0.1,
8385         256,    64,     0.1,
8386         320,    64,     0.1,
8387         384,    64,     0.1,
8388         448,    64,     0.1,
8389         512,    64,     0.1,
8390     };
8391
8392     /* 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 */
8393     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;
8394     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;
8395     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;
8396     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;
8397
8398     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;
8399     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;
8400     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;
8401     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;
8402
8403     memset(&caps, 0, sizeof(caps));
8404     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8405     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8406     if(caps.MaxPointSize < 32.0) {
8407         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8408         return;
8409     }
8410
8411     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8412     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8413     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8414     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8415     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8416     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8417     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8418     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8419
8420     hr = IDirect3DDevice9_BeginScene(device);
8421     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8422     if (SUCCEEDED(hr))
8423     {
8424         ptsize = 15.0;
8425         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8426         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8427         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8428         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8429
8430         ptsize = 31.0;
8431         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8432         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8433         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8434         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8435
8436         ptsize = 30.75;
8437         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8438         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8439         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8440         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8441
8442         if (caps.MaxPointSize >= 63.0)
8443         {
8444             ptsize = 63.0;
8445             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8446             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8447             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8448             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8449
8450             ptsize = 62.75;
8451             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8452             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8454             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8455         }
8456
8457         ptsize = 1.0;
8458         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8459         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8460         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8461         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8462
8463         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8464         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8465         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8466         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8467
8468         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8469         ptsize = 15.0;
8470         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8471         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8472         ptsize = 1.0;
8473         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8474         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8475         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8476         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8477
8478         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8479         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8480
8481         /* pointsize < pointsize_min < pointsize_max?
8482          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8483         ptsize = 1.0;
8484         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8485         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8486         ptsize = 15.0;
8487         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8488         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8489         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8490         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8491
8492         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8493         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8494
8495         hr = IDirect3DDevice9_EndScene(device);
8496         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8497     }
8498
8499     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8500     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8501     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8502
8503     if (caps.MaxPointSize >= 63.0)
8504     {
8505         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8506         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8507     }
8508
8509     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8510     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8511     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8512     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8513     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8514
8515     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8516
8517     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8518      * generates texture coordinates for the point(result: Yes, it does)
8519      *
8520      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8521      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8522      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8523      */
8524     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8525     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8526
8527     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8528     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8529     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8530     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8531     memset(&lr, 0, sizeof(lr));
8532     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8533     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8534     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8535     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8536     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8537     memset(&lr, 0, sizeof(lr));
8538     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8539     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8540     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8541     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8542     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8543     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8544     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8545     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8546     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8547     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8548     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8549     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8550     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8551     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8552     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8553     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8554     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8555     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8557
8558     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8559     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8560     ptsize = 32.0;
8561     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8562     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8563
8564     hr = IDirect3DDevice9_BeginScene(device);
8565     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8566     if(SUCCEEDED(hr))
8567     {
8568         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8569         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8570         hr = IDirect3DDevice9_EndScene(device);
8571         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8572     }
8573
8574     color = getPixelColor(device, 64-4, 64-4);
8575     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8576     color = getPixelColor(device, 64-4, 64+4);
8577     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8578     color = getPixelColor(device, 64+4, 64+4);
8579     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8580     color = getPixelColor(device, 64+4, 64-4);
8581     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8582     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8583
8584     U(matrix).m[0][0] =  1.0f / 64.0f;
8585     U(matrix).m[1][1] = -1.0f / 64.0f;
8586     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8587     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8588
8589     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8590     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8591
8592     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8593             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8594     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8595
8596     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8597     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8598     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8599     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8600
8601     hr = IDirect3DDevice9_BeginScene(device);
8602     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8603     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8604     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8605     hr = IDirect3DDevice9_EndScene(device);
8606     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8607
8608     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8609     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8610     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8611     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8612     IDirect3DSurface9_Release(backbuffer);
8613     IDirect3DSurface9_Release(rt);
8614
8615     color = getPixelColor(device, 64-4, 64-4);
8616     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8617             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8618     color = getPixelColor(device, 64+4, 64-4);
8619     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8620             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8621     color = getPixelColor(device, 64-4, 64+4);
8622     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8623             "Expected color 0x00000000, got 0x%08x.\n", color);
8624     color = getPixelColor(device, 64+4, 64+4);
8625     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8626             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8627
8628     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8629     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8630
8631     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8632     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8633     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8634     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8635     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8636     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8637     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8638     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8639     IDirect3DTexture9_Release(tex1);
8640     IDirect3DTexture9_Release(tex2);
8641
8642     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8643     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8645     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8646     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8647     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8648 }
8649
8650 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8651 {
8652     static const DWORD vshader_code[] =
8653     {
8654         0xfffe0300,                                                             /* vs_3_0                     */
8655         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8656         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8657         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8658         0x0000ffff                                                              /* end                        */
8659     };
8660     static const DWORD pshader_code[] =
8661     {
8662         0xffff0300,                                                             /* ps_3_0                     */
8663         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8664         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8665         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8666         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8667         0x0000ffff                                                              /* end                        */
8668     };
8669
8670     HRESULT hr;
8671     IDirect3DVertexShader9 *vs;
8672     IDirect3DPixelShader9 *ps;
8673     IDirect3DTexture9 *tex1, *tex2;
8674     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8675     D3DCAPS9 caps;
8676     DWORD color;
8677     float quad[] = {
8678        -1.0,   -1.0,    0.1,
8679         1.0,   -1.0,    0.1,
8680        -1.0,    1.0,    0.1,
8681         1.0,    1.0,    0.1,
8682     };
8683     float texquad[] = {
8684        -1.0,   -1.0,    0.1,    0.0,    0.0,
8685         0.0,   -1.0,    0.1,    1.0,    0.0,
8686        -1.0,    1.0,    0.1,    0.0,    1.0,
8687         0.0,    1.0,    0.1,    1.0,    1.0,
8688
8689         0.0,   -1.0,    0.1,    0.0,    0.0,
8690         1.0,   -1.0,    0.1,    1.0,    0.0,
8691         0.0,    1.0,    0.1,    0.0,    1.0,
8692         1.0,    1.0,    0.1,    1.0,    1.0,
8693     };
8694
8695     memset(&caps, 0, sizeof(caps));
8696     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8697     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8698     if(caps.NumSimultaneousRTs < 2) {
8699         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8700         return;
8701     }
8702
8703     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8704     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8705
8706     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8707             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8708     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8709
8710     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8711             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8712     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8713     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8714             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8715     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8716     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8717     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8718     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8719     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8720
8721     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8722     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8723     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8724     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8725     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8726     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8727
8728     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8729     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8730     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8731     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8732     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8733     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8734     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8735     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8736     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8737     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8738
8739     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8740     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8741     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8742     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8743     color = getPixelColorFromSurface(readback, 8, 8);
8744     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8745             "Expected color 0x000000ff, got 0x%08x.\n", color);
8746     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8747     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8748     color = getPixelColorFromSurface(readback, 8, 8);
8749     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8750             "Expected color 0x000000ff, got 0x%08x.\n", color);
8751
8752     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8753     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8754     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8755     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8756     color = getPixelColorFromSurface(readback, 8, 8);
8757     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8758             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8759     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8760     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8761     color = getPixelColorFromSurface(readback, 8, 8);
8762     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8763             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8764
8765     hr = IDirect3DDevice9_BeginScene(device);
8766     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8767     if(SUCCEEDED(hr)) {
8768         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8769         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8770
8771         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8772         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8773         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8774         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8775         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8776         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8777         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8778         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8779         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8780         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8781
8782         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8783         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8784         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8785         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8786
8787         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8788         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8789         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8790         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8791
8792         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8793         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8794
8795         hr = IDirect3DDevice9_EndScene(device);
8796         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8797     }
8798
8799     color = getPixelColor(device, 160, 240);
8800     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8801     color = getPixelColor(device, 480, 240);
8802     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8803     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8804
8805     IDirect3DPixelShader9_Release(ps);
8806     IDirect3DVertexShader9_Release(vs);
8807     IDirect3DTexture9_Release(tex1);
8808     IDirect3DTexture9_Release(tex2);
8809     IDirect3DSurface9_Release(surf1);
8810     IDirect3DSurface9_Release(surf2);
8811     IDirect3DSurface9_Release(backbuf);
8812     IDirect3DSurface9_Release(readback);
8813 }
8814
8815 struct formats {
8816     const char *fmtName;
8817     D3DFORMAT textureFormat;
8818     DWORD resultColorBlending;
8819     DWORD resultColorNoBlending;
8820 };
8821
8822 static const struct formats test_formats[] = {
8823   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8824   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8825   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8826   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8827   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8828   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8829   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8830   { NULL, 0 }
8831 };
8832
8833 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8834 {
8835     HRESULT hr;
8836     IDirect3DTexture9 *offscreenTexture = NULL;
8837     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8838     IDirect3D9 *d3d = NULL;
8839     DWORD color;
8840     DWORD r0, g0, b0, r1, g1, b1;
8841     int fmt_index;
8842
8843     static const float quad[][5] = {
8844         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8845         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8846         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8847         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8848     };
8849
8850     /* Quad with R=0x10, G=0x20 */
8851     static const struct vertex quad1[] = {
8852         {-1.0f, -1.0f, 0.1f, 0x80102000},
8853         {-1.0f,  1.0f, 0.1f, 0x80102000},
8854         { 1.0f, -1.0f, 0.1f, 0x80102000},
8855         { 1.0f,  1.0f, 0.1f, 0x80102000},
8856     };
8857
8858     /* Quad with R=0x20, G=0x10 */
8859     static const struct vertex quad2[] = {
8860         {-1.0f, -1.0f, 0.1f, 0x80201000},
8861         {-1.0f,  1.0f, 0.1f, 0x80201000},
8862         { 1.0f, -1.0f, 0.1f, 0x80201000},
8863         { 1.0f,  1.0f, 0.1f, 0x80201000},
8864     };
8865
8866     IDirect3DDevice9_GetDirect3D(device, &d3d);
8867
8868     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8869     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8870     if(!backbuffer) {
8871         goto out;
8872     }
8873
8874     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8875     {
8876         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8877         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8878            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8879            continue;
8880         }
8881
8882         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8883         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8884
8885         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8886         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8887         if(!offscreenTexture) {
8888             continue;
8889         }
8890
8891         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8892         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8893         if(!offscreen) {
8894             continue;
8895         }
8896
8897         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8898         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8899
8900         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8901         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8902         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8903         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8904         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8905         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8906         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8907         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8908         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8909         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8910
8911         /* Below we will draw two quads with different colors and try to blend them together.
8912          * The result color is compared with the expected outcome.
8913          */
8914         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8915             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8916             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8917             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8918             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8919
8920             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8921             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8922
8923             /* Draw a quad using color 0x0010200 */
8924             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8925             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8926             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8927             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8928             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8929             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8930
8931             /* Draw a quad using color 0x0020100 */
8932             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8933             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8934             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8935             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8936             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8937             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8938
8939             /* We don't want to blend the result on the backbuffer */
8940             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8941             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8942
8943             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8944             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8945             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8946             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8947             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8948
8949             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8950             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8951
8952             /* This time with the texture */
8953             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8954             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8955
8956             IDirect3DDevice9_EndScene(device);
8957         }
8958
8959         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8960             /* Compare the color of the center quad with our expectation */
8961             color = getPixelColor(device, 320, 240);
8962             r0 = (color & 0x00ff0000) >> 16;
8963             g0 = (color & 0x0000ff00) >>  8;
8964             b0 = (color & 0x000000ff) >>  0;
8965
8966             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8967             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8968             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8969
8970             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8971                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8972                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8973                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8974         } else {
8975             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8976              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8977              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8978             color = getPixelColor(device, 320, 240);
8979             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);
8980         }
8981         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8982
8983         IDirect3DDevice9_SetTexture(device, 0, NULL);
8984         if(offscreenTexture) {
8985             IDirect3DTexture9_Release(offscreenTexture);
8986         }
8987         if(offscreen) {
8988             IDirect3DSurface9_Release(offscreen);
8989         }
8990     }
8991
8992 out:
8993     /* restore things */
8994     if(backbuffer) {
8995         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8996         IDirect3DSurface9_Release(backbuffer);
8997     }
8998 }
8999
9000 static void tssargtemp_test(IDirect3DDevice9 *device)
9001 {
9002     HRESULT hr;
9003     DWORD color;
9004     static const struct vertex quad[] = {
9005         {-1.0,     -1.0,    0.1,    0x00ff0000},
9006         { 1.0,     -1.0,    0.1,    0x00ff0000},
9007         {-1.0,      1.0,    0.1,    0x00ff0000},
9008         { 1.0,      1.0,    0.1,    0x00ff0000}
9009     };
9010     D3DCAPS9 caps;
9011
9012     memset(&caps, 0, sizeof(caps));
9013     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9014     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9015     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9016         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9017         return;
9018     }
9019
9020     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9021     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9022
9023     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9024     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9025     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9026     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9027
9028     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9029     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9030     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9031     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9032     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9033     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9034
9035     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9036     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9037     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9038     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9039     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9040     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9041
9042     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9043     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9044
9045     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9046     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9047     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9048     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9049
9050     hr = IDirect3DDevice9_BeginScene(device);
9051     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9052     if(SUCCEEDED(hr)) {
9053         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9054         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9055         hr = IDirect3DDevice9_EndScene(device);
9056         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9057     }
9058     color = getPixelColor(device, 320, 240);
9059     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9060     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9061
9062     /* Set stage 1 back to default */
9063     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9064     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9065     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9066     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9067     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9068     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9069     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9070     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9071     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9072     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9073 }
9074
9075 struct testdata
9076 {
9077     DWORD idxVertex; /* number of instances in the first stream */
9078     DWORD idxColor; /* number of instances in the second stream */
9079     DWORD idxInstance; /* should be 1 ?? */
9080     DWORD color1; /* color 1 instance */
9081     DWORD color2; /* color 2 instance */
9082     DWORD color3; /* color 3 instance */
9083     DWORD color4; /* color 4 instance */
9084     WORD strVertex; /* specify which stream to use 0-2*/
9085     WORD strColor;
9086     WORD strInstance;
9087 };
9088
9089 static const struct testdata testcases[]=
9090 {
9091     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9092     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9093     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9094     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9095     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9096     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9097     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9098     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9099     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9100     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9101     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9102     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9103     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9104     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9105     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9106 /*
9107     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9108     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9109 */
9110 };
9111
9112 /* Drawing Indexed Geometry with instances*/
9113 static void stream_test(IDirect3DDevice9 *device)
9114 {
9115     IDirect3DVertexBuffer9 *vb = NULL;
9116     IDirect3DVertexBuffer9 *vb2 = NULL;
9117     IDirect3DVertexBuffer9 *vb3 = NULL;
9118     IDirect3DIndexBuffer9 *ib = NULL;
9119     IDirect3DVertexDeclaration9 *pDecl = NULL;
9120     IDirect3DVertexShader9 *shader = NULL;
9121     HRESULT hr;
9122     BYTE *data;
9123     DWORD color;
9124     DWORD ind;
9125     unsigned i;
9126
9127     const DWORD shader_code[] =
9128     {
9129         0xfffe0101,                                     /* vs_1_1 */
9130         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9131         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9132         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9133         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9134         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9135         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9136         0x0000ffff
9137     };
9138
9139     const float quad[][3] =
9140     {
9141         {-0.5f, -0.5f,  1.1f}, /*0 */
9142         {-0.5f,  0.5f,  1.1f}, /*1 */
9143         { 0.5f, -0.5f,  1.1f}, /*2 */
9144         { 0.5f,  0.5f,  1.1f}, /*3 */
9145     };
9146
9147     const float vertcolor[][4] =
9148     {
9149         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9150         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9151         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9152         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9153     };
9154
9155     /* 4 position for 4 instances */
9156     const float instancepos[][3] =
9157     {
9158         {-0.6f,-0.6f, 0.0f},
9159         { 0.6f,-0.6f, 0.0f},
9160         { 0.6f, 0.6f, 0.0f},
9161         {-0.6f, 0.6f, 0.0f},
9162     };
9163
9164     short indices[] = {0, 1, 2, 1, 2, 3};
9165
9166     D3DVERTEXELEMENT9 decl[] =
9167     {
9168         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9169         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9170         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9171         D3DDECL_END()
9172     };
9173
9174     /* set the default value because it isn't done in wine? */
9175     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9176     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9177
9178     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9179     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9180     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9181
9182     /* check wrong cases */
9183     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9184     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9185     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9186     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9187     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9188     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9189     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9190     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9191     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9192     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9193     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9194     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9195     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9196     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9197     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9198     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9199     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9200     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9201     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9202     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9203
9204     /* set the default value back */
9205     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9206     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9207
9208     /* create all VertexBuffers*/
9209     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9210     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9211     if(!vb) {
9212         skip("Failed to create a vertex buffer\n");
9213         return;
9214     }
9215     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9216     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9217     if(!vb2) {
9218         skip("Failed to create a vertex buffer\n");
9219         goto out;
9220     }
9221     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9222     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9223     if(!vb3) {
9224         skip("Failed to create a vertex buffer\n");
9225         goto out;
9226     }
9227
9228     /* create IndexBuffer*/
9229     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9230     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9231     if(!ib) {
9232         skip("Failed to create a index buffer\n");
9233         goto out;
9234     }
9235
9236     /* copy all Buffers (Vertex + Index)*/
9237     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9238     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9239     memcpy(data, quad, sizeof(quad));
9240     hr = IDirect3DVertexBuffer9_Unlock(vb);
9241     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9242     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9243     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9244     memcpy(data, vertcolor, sizeof(vertcolor));
9245     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9246     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9247     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9248     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9249     memcpy(data, instancepos, sizeof(instancepos));
9250     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9251     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9252     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9253     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9254     memcpy(data, indices, sizeof(indices));
9255     hr = IDirect3DIndexBuffer9_Unlock(ib);
9256     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9257
9258     /* create VertexShader */
9259     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9260     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9261     if(!shader) {
9262         skip("Failed to create a vetex shader\n");
9263         goto out;
9264     }
9265
9266     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9267     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9268
9269     hr = IDirect3DDevice9_SetIndices(device, ib);
9270     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9271
9272     /* run all tests */
9273     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9274     {
9275         struct testdata act = testcases[i];
9276         decl[0].Stream = act.strVertex;
9277         decl[1].Stream = act.strColor;
9278         decl[2].Stream = act.strInstance;
9279         /* create VertexDeclarations */
9280         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9281         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9282
9283         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9284         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9285
9286         hr = IDirect3DDevice9_BeginScene(device);
9287         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9288         if(SUCCEEDED(hr))
9289         {
9290             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9291             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9292
9293             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9294             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9295             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9296             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9297
9298             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9299             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9300             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9301             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9302
9303             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9304             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9305             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9306             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9307
9308             /* don't know if this is right (1*3 and 4*1)*/
9309             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9310             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9311             hr = IDirect3DDevice9_EndScene(device);
9312             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9313
9314             /* set all StreamSource && StreamSourceFreq back to default */
9315             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9316             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9317             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9318             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9319             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9320             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9321             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9322             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9323             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9324             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9325             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9326             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9327         }
9328
9329         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9330         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9331
9332         color = getPixelColor(device, 160, 360);
9333         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9334         color = getPixelColor(device, 480, 360);
9335         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9336         color = getPixelColor(device, 480, 120);
9337         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9338         color = getPixelColor(device, 160, 120);
9339         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9340
9341         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9342         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9343     }
9344
9345     hr = IDirect3DDevice9_SetIndices(device, NULL);
9346     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9347
9348 out:
9349     if(vb) IDirect3DVertexBuffer9_Release(vb);
9350     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9351     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9352     if(ib)IDirect3DIndexBuffer9_Release(ib);
9353     if(shader)IDirect3DVertexShader9_Release(shader);
9354 }
9355
9356 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9357     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9358     IDirect3DTexture9 *dsttex = NULL;
9359     HRESULT hr;
9360     DWORD color;
9361     D3DRECT r1 = {0,  0,  50,  50 };
9362     D3DRECT r2 = {50, 0,  100, 50 };
9363     D3DRECT r3 = {50, 50, 100, 100};
9364     D3DRECT r4 = {0,  50,  50, 100};
9365     const float quad[] = {
9366         -1.0,   -1.0,   0.1,    0.0,    0.0,
9367          1.0,   -1.0,   0.1,    1.0,    0.0,
9368         -1.0,    1.0,   0.1,    0.0,    1.0,
9369          1.0,    1.0,   0.1,    1.0,    1.0,
9370     };
9371
9372     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9373     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9374
9375     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9376     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9377     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9378     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9379
9380     if(!src || !dsttex) {
9381         skip("One or more test resources could not be created\n");
9382         goto cleanup;
9383     }
9384
9385     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9386     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9387
9388     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9389     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9390
9391     /* Clear the StretchRect destination for debugging */
9392     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9393     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9394     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9395     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9396
9397     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9398     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9399
9400     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9401     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9402     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9403     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9404     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9405     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9406     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9407     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9408
9409     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9410      * the target -> texture GL blit path
9411      */
9412     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9413     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9414     IDirect3DSurface9_Release(dst);
9415
9416     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9417     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9418
9419     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9420     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9421     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9422     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9423     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9424     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9425     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9426     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9427
9428     hr = IDirect3DDevice9_BeginScene(device);
9429     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9430     if(SUCCEEDED(hr)) {
9431         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9432         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9433         hr = IDirect3DDevice9_EndScene(device);
9434         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9435     }
9436
9437     color = getPixelColor(device, 160, 360);
9438     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9439     color = getPixelColor(device, 480, 360);
9440     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9441     color = getPixelColor(device, 480, 120);
9442     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9443     color = getPixelColor(device, 160, 120);
9444     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9447
9448     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9449     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9450     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9451     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9452
9453 cleanup:
9454     if(src) IDirect3DSurface9_Release(src);
9455     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9456     if(dsttex) IDirect3DTexture9_Release(dsttex);
9457 }
9458
9459 static void texop_test(IDirect3DDevice9 *device)
9460 {
9461     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9462     IDirect3DTexture9 *texture = NULL;
9463     D3DLOCKED_RECT locked_rect;
9464     D3DCOLOR color;
9465     D3DCAPS9 caps;
9466     HRESULT hr;
9467     unsigned i;
9468
9469     static const struct {
9470         float x, y, z;
9471         float s, t;
9472         D3DCOLOR diffuse;
9473     } quad[] = {
9474         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9475         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9476         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9477         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9478     };
9479
9480     static const D3DVERTEXELEMENT9 decl_elements[] = {
9481         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9482         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9483         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9484         D3DDECL_END()
9485     };
9486
9487     static const struct {
9488         D3DTEXTUREOP op;
9489         const char *name;
9490         DWORD caps_flag;
9491         D3DCOLOR result;
9492     } test_data[] = {
9493         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9494         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9495         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9496         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9497         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9498         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9499         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9500         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9501         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9502         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9503         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9504         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9505         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9506         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9507         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9508         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9509         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9510         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9511         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9512         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9513         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9514         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9515         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9516     };
9517
9518     memset(&caps, 0, sizeof(caps));
9519     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9520     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9521
9522     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9523     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9524     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9525     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9526
9527     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9528     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9529     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9530     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9531     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9532     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9533     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9534     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9535     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9536
9537     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9538     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9539     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9540     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9541     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9542     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9543
9544     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9545     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9546
9547     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9548     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9549     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9550     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9551     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9552     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9553
9554     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9555     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9556
9557     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9558     {
9559         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9560         {
9561             skip("tex operation %s not supported\n", test_data[i].name);
9562             continue;
9563         }
9564
9565         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9566         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9567
9568         hr = IDirect3DDevice9_BeginScene(device);
9569         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9570
9571         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9572         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9573
9574         hr = IDirect3DDevice9_EndScene(device);
9575         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9576
9577         color = getPixelColor(device, 320, 240);
9578         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9579                 test_data[i].name, color, test_data[i].result);
9580
9581         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9582         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9583     }
9584
9585     if (texture) IDirect3DTexture9_Release(texture);
9586     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9587 }
9588
9589 static void yuv_color_test(IDirect3DDevice9 *device) {
9590     HRESULT hr;
9591     IDirect3DSurface9 *surface = NULL, *target = NULL;
9592     unsigned int fmt, i;
9593     D3DFORMAT format;
9594     const char *fmt_string;
9595     D3DLOCKED_RECT lr;
9596     IDirect3D9 *d3d;
9597     HRESULT color;
9598     DWORD ref_color_left, ref_color_right;
9599
9600     struct {
9601         DWORD in;           /* The input color */
9602         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9603         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9604         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9605         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9606     } test_data[] = {
9607     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9608      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9609      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9610      * that
9611      */
9612       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9613       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9614       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9615       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9616       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9617       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9618       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9619       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9620       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9621       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9622       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9623       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9624       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9625       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9626
9627       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9628       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9629       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9630       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9631     };
9632
9633     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9634     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9635     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9636     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9637
9638     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9639     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9640
9641     for(fmt = 0; fmt < 2; fmt++) {
9642         if(fmt == 0) {
9643             format = D3DFMT_UYVY;
9644             fmt_string = "D3DFMT_UYVY";
9645         } else {
9646             format = D3DFMT_YUY2;
9647             fmt_string = "D3DFMT_YUY2";
9648         }
9649
9650         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9651                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9652                        */
9653         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9654                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9655             skip("%s is not supported\n", fmt_string);
9656             continue;
9657         }
9658
9659         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9660         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9661         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9662
9663         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9664             if(fmt == 0) {
9665                 ref_color_left = test_data[i].uyvy_left;
9666                 ref_color_right = test_data[i].uyvy_right;
9667             } else {
9668                 ref_color_left = test_data[i].yuy2_left;
9669                 ref_color_right = test_data[i].yuy2_right;
9670             }
9671
9672             memset(&lr, 0, sizeof(lr));
9673             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9674             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9675             *((DWORD *) lr.pBits) = test_data[i].in;
9676             hr = IDirect3DSurface9_UnlockRect(surface);
9677             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9678
9679             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9680             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9681             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9682             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9683
9684             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9685              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9686              * want to add tests for the filtered pixels as well.
9687              *
9688              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9689              * differently, so we need a max diff of 16
9690              */
9691             color = getPixelColor(device, 40, 240);
9692             ok(color_match(color, ref_color_left, 18),
9693                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9694                test_data[i].in, color, ref_color_left, fmt_string);
9695             color = getPixelColor(device, 600, 240);
9696             ok(color_match(color, ref_color_right, 18),
9697                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9698                test_data[i].in, color, ref_color_right, fmt_string);
9699             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9700             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9701         }
9702         IDirect3DSurface9_Release(surface);
9703     }
9704     IDirect3DSurface9_Release(target);
9705     IDirect3D9_Release(d3d);
9706 }
9707
9708 static void texop_range_test(IDirect3DDevice9 *device)
9709 {
9710     static const struct {
9711         float x, y, z;
9712         D3DCOLOR diffuse;
9713     } quad[] = {
9714         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9715         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9716         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9717         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9718     };
9719     HRESULT hr;
9720     IDirect3DTexture9 *texture;
9721     D3DLOCKED_RECT locked_rect;
9722     D3DCAPS9 caps;
9723     DWORD color;
9724
9725     /* We need ADD and SUBTRACT operations */
9726     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9727     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9728     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9729         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9730         return;
9731     }
9732     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9733         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9734         return;
9735     }
9736
9737     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9738     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9739     /* Stage 1: result = diffuse(=1.0) + diffuse
9740      * stage 2: result = result - tfactor(= 0.5)
9741      */
9742     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9743     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9744     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9745     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9746     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9747     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9748     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9749     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9750     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9751     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9752     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9753     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9754     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9755     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9756
9757     hr = IDirect3DDevice9_BeginScene(device);
9758     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9759     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9760     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9761     hr = IDirect3DDevice9_EndScene(device);
9762     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9763
9764     color = getPixelColor(device, 320, 240);
9765     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9766        color);
9767     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9768     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9769
9770     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9771     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9772     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9773     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9774     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9775     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9776     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9777     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9778     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9779
9780     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9781      * stage 2: result = result + diffuse(1.0)
9782      */
9783     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9784     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9785     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9786     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9787     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9788     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9789     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9790     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9791     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9792     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9793     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9794     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9795     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9796     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9797
9798     hr = IDirect3DDevice9_BeginScene(device);
9799     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9800     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9801     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9802     hr = IDirect3DDevice9_EndScene(device);
9803     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9804
9805     color = getPixelColor(device, 320, 240);
9806     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9807        color);
9808     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9809     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9810
9811     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9812     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9813     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9814     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9815     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9816     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9817     IDirect3DTexture9_Release(texture);
9818 }
9819
9820 static void alphareplicate_test(IDirect3DDevice9 *device) {
9821     struct vertex quad[] = {
9822         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9823         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9824         { -1.0,     1.0,    0.1,    0x80ff00ff },
9825         {  1.0,     1.0,    0.1,    0x80ff00ff },
9826     };
9827     HRESULT hr;
9828     DWORD color;
9829
9830     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9831     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9832
9833     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9834     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9835
9836     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9837     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9838     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9839     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9840
9841     hr = IDirect3DDevice9_BeginScene(device);
9842     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9843     if(SUCCEEDED(hr)) {
9844         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9845         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9846         hr = IDirect3DDevice9_EndScene(device);
9847         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9848     }
9849
9850     color = getPixelColor(device, 320, 240);
9851     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9852        color);
9853     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9854     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9855
9856     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9857     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9858
9859 }
9860
9861 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9862     HRESULT hr;
9863     D3DCAPS9 caps;
9864     DWORD color;
9865     struct vertex quad[] = {
9866         { -1.0,    -1.0,    0.1,    0x408080c0 },
9867         {  1.0,    -1.0,    0.1,    0x408080c0 },
9868         { -1.0,     1.0,    0.1,    0x408080c0 },
9869         {  1.0,     1.0,    0.1,    0x408080c0 },
9870     };
9871
9872     memset(&caps, 0, sizeof(caps));
9873     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9874     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9875     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9876         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9877         return;
9878     }
9879
9880     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9881     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9882
9883     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9884     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9885
9886     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9887      * mov r0.a, diffuse.a
9888      * mov r0, r0.a
9889      *
9890      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9891      * 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
9892      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9893      */
9894     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9895     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9896     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9897     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9898     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9899     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9900     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9901     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9902     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9903     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9904     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9905     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9906     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9907     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9908     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9909     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9910     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9911     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9912
9913     hr = IDirect3DDevice9_BeginScene(device);
9914     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9915     if(SUCCEEDED(hr)) {
9916         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9917         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9918         hr = IDirect3DDevice9_EndScene(device);
9919         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9920     }
9921
9922     color = getPixelColor(device, 320, 240);
9923     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9924        color);
9925     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9926     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9927
9928     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9929     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9930     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9931     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9932     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9933     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9934 }
9935
9936 static void zwriteenable_test(IDirect3DDevice9 *device) {
9937     HRESULT hr;
9938     DWORD color;
9939     struct vertex quad1[] = {
9940         { -1.0,  -1.0,  0.1,    0x00ff0000},
9941         { -1.0,   1.0,  0.1,    0x00ff0000},
9942         {  1.0,  -1.0,  0.1,    0x00ff0000},
9943         {  1.0,   1.0,  0.1,    0x00ff0000},
9944     };
9945     struct vertex quad2[] = {
9946         { -1.0,  -1.0,  0.9,    0x0000ff00},
9947         { -1.0,   1.0,  0.9,    0x0000ff00},
9948         {  1.0,  -1.0,  0.9,    0x0000ff00},
9949         {  1.0,   1.0,  0.9,    0x0000ff00},
9950     };
9951
9952     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9953     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9954
9955     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9956     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9957     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9958     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9959     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9960     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9961     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9962     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9963
9964     hr = IDirect3DDevice9_BeginScene(device);
9965     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9966     if(SUCCEEDED(hr)) {
9967         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9968          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9969          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9970          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9971          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9972          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9973          */
9974         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9975         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9976         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9977         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9978         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9979         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9980
9981         hr = IDirect3DDevice9_EndScene(device);
9982         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9983     }
9984
9985     color = getPixelColor(device, 320, 240);
9986     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9987        color);
9988     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9989     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9990
9991     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9992     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9993 }
9994
9995 static void alphatest_test(IDirect3DDevice9 *device) {
9996 #define ALPHATEST_PASSED 0x0000ff00
9997 #define ALPHATEST_FAILED 0x00ff0000
9998     struct {
9999         D3DCMPFUNC  func;
10000         DWORD       color_less;
10001         DWORD       color_equal;
10002         DWORD       color_greater;
10003     } testdata[] = {
10004         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10005         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10006         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10007         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10008         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10009         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10010         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10011         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10012     };
10013     unsigned int i, j;
10014     HRESULT hr;
10015     DWORD color;
10016     struct vertex quad[] = {
10017         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10018         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10019         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10020         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10021     };
10022     D3DCAPS9 caps;
10023
10024     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10025     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10026     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10027     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10028
10029     for(j = 0; j < 2; j++) {
10030         if(j == 1) {
10031             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10032              * the alpha test either for performance reasons(floating point RTs) or to work
10033              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10034              * codepath for ffp and shader in this case, and the test should cover both
10035              */
10036             IDirect3DPixelShader9 *ps;
10037             DWORD shader_code[] = {
10038                 0xffff0101,                                 /* ps_1_1           */
10039                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10040                 0x0000ffff                                  /* end              */
10041             };
10042             memset(&caps, 0, sizeof(caps));
10043             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10044             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10045             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10046                 break;
10047             }
10048
10049             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10050             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10051             IDirect3DDevice9_SetPixelShader(device, ps);
10052             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10053             IDirect3DPixelShader9_Release(ps);
10054         }
10055
10056         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10057             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10058             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10059
10060             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10061             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10062             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
10063             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10064             hr = IDirect3DDevice9_BeginScene(device);
10065             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10066             if(SUCCEEDED(hr)) {
10067                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10068                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10069                 hr = IDirect3DDevice9_EndScene(device);
10070                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10071             }
10072             color = getPixelColor(device, 320, 240);
10073             ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10074             color, testdata[i].color_less, testdata[i].func);
10075             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10076             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10077
10078             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10079             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10080             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
10081             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10082             hr = IDirect3DDevice9_BeginScene(device);
10083             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10084             if(SUCCEEDED(hr)) {
10085                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10086                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10087                 hr = IDirect3DDevice9_EndScene(device);
10088                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10089             }
10090             color = getPixelColor(device, 320, 240);
10091             ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10092             color, testdata[i].color_equal, testdata[i].func);
10093             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10094             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10095
10096             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10097             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10098             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10099             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10100             hr = IDirect3DDevice9_BeginScene(device);
10101             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10102             if(SUCCEEDED(hr)) {
10103                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10104                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10105                 hr = IDirect3DDevice9_EndScene(device);
10106                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10107             }
10108             color = getPixelColor(device, 320, 240);
10109             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10110             color, testdata[i].color_greater, testdata[i].func);
10111             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10112             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10113         }
10114     }
10115
10116     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10117     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10118     IDirect3DDevice9_SetPixelShader(device, NULL);
10119     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10120 }
10121
10122 static void sincos_test(IDirect3DDevice9 *device) {
10123     const DWORD sin_shader_code[] = {
10124         0xfffe0200,                                                                 /* vs_2_0                       */
10125         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10126         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10127         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10128         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10129         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10130         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10131         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10132         0x0000ffff                                                                  /* end                          */
10133     };
10134     const DWORD cos_shader_code[] = {
10135         0xfffe0200,                                                                 /* vs_2_0                       */
10136         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10137         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10138         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10139         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10140         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10141         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10142         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10143         0x0000ffff                                                                  /* end                          */
10144     };
10145     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10146     HRESULT hr;
10147     struct {
10148         float x, y, z;
10149     } data[1280];
10150     unsigned int i;
10151     float sincosc1[4] = {D3DSINCOSCONST1};
10152     float sincosc2[4] = {D3DSINCOSCONST2};
10153
10154     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10155     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10156
10157     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10158     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10159     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10160     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10161     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10162     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10163     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10164     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10165     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10166     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10167
10168     /* Generate a point from -1 to 1 every 0.5 pixels */
10169     for(i = 0; i < 1280; i++) {
10170         data[i].x = (-640.0 + i) / 640.0;
10171         data[i].y = 0.0;
10172         data[i].z = 0.1;
10173     }
10174
10175     hr = IDirect3DDevice9_BeginScene(device);
10176     if(SUCCEEDED(hr)) {
10177         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10178         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10179         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10180         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10181
10182         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10183         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10184         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10185         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10186
10187         hr = IDirect3DDevice9_EndScene(device);
10188         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10189     }
10190     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10191     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10192     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10193
10194     IDirect3DDevice9_SetVertexShader(device, NULL);
10195     IDirect3DVertexShader9_Release(sin_shader);
10196     IDirect3DVertexShader9_Release(cos_shader);
10197 }
10198
10199 static void loop_index_test(IDirect3DDevice9 *device) {
10200     const DWORD shader_code[] = {
10201         0xfffe0200,                                                 /* vs_2_0                   */
10202         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10203         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10204         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10205         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10206         0x0000001d,                                                 /* endloop                  */
10207         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10208         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10209         0x0000ffff                                                  /* END                      */
10210     };
10211     IDirect3DVertexShader9 *shader;
10212     HRESULT hr;
10213     DWORD color;
10214     const float quad[] = {
10215         -1.0,   -1.0,   0.1,
10216          1.0,   -1.0,   0.1,
10217         -1.0,    1.0,   0.1,
10218          1.0,    1.0,   0.1
10219     };
10220     const float zero[4] = {0, 0, 0, 0};
10221     const float one[4] = {1, 1, 1, 1};
10222     int i0[4] = {2, 10, -3, 0};
10223     float values[4];
10224
10225     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10226     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10227     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10228     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10229     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10230     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10231     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10232     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10233
10234     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10235     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10236     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10237     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10238     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10239     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10240     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10241     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10242     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10243     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10244     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10245     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10246     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10247     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10248     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10249     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10250     values[0] = 1.0;
10251     values[1] = 1.0;
10252     values[2] = 0.0;
10253     values[3] = 0.0;
10254     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10255     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10256     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10257     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10258     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10259     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10260     values[0] = -1.0;
10261     values[1] = 0.0;
10262     values[2] = 0.0;
10263     values[3] = 0.0;
10264     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10265     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10266     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10267     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10268     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10269     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10270     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10271     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10272     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10273     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10274
10275     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10276     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10277
10278     hr = IDirect3DDevice9_BeginScene(device);
10279     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10280     if(SUCCEEDED(hr))
10281     {
10282         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10283         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10284         hr = IDirect3DDevice9_EndScene(device);
10285         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10286     }
10287     color = getPixelColor(device, 320, 240);
10288     ok(color_match(color, 0x0000ff00, 1),
10289        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10290     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10291     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10292
10293     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10294     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10295     IDirect3DVertexShader9_Release(shader);
10296 }
10297
10298 static void sgn_test(IDirect3DDevice9 *device) {
10299     const DWORD shader_code[] = {
10300         0xfffe0200,                                                             /* vs_2_0                       */
10301         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10302         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10303         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10304         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10305         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10306         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10307         0x0000ffff                                                              /* end                          */
10308     };
10309     IDirect3DVertexShader9 *shader;
10310     HRESULT hr;
10311     DWORD color;
10312     const float quad[] = {
10313         -1.0,   -1.0,   0.1,
10314          1.0,   -1.0,   0.1,
10315         -1.0,    1.0,   0.1,
10316          1.0,    1.0,   0.1
10317     };
10318
10319     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10320     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10321     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10322     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10323     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10324     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10325     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10326     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10327
10328     hr = IDirect3DDevice9_BeginScene(device);
10329     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10330     if(SUCCEEDED(hr))
10331     {
10332         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10333         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10334         hr = IDirect3DDevice9_EndScene(device);
10335         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10336     }
10337     color = getPixelColor(device, 320, 240);
10338     ok(color_match(color, 0x008000ff, 1),
10339        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10340     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10341     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10342
10343     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10344     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10345     IDirect3DVertexShader9_Release(shader);
10346 }
10347
10348 static void viewport_test(IDirect3DDevice9 *device) {
10349     HRESULT hr;
10350     DWORD color;
10351     D3DVIEWPORT9 vp, old_vp;
10352     BOOL draw_failed = TRUE;
10353     const float quad[] =
10354     {
10355         -0.5,   -0.5,   0.1,
10356          0.5,   -0.5,   0.1,
10357         -0.5,    0.5,   0.1,
10358          0.5,    0.5,   0.1
10359     };
10360
10361     memset(&old_vp, 0, sizeof(old_vp));
10362     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10363     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10364
10365     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10366     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10367
10368     /* Test a viewport with Width and Height bigger than the surface dimensions
10369      *
10370      * TODO: Test Width < surface.width, but X + Width > surface.width
10371      * TODO: Test Width < surface.width, what happens with the height?
10372      *
10373      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10374      * and Height fields bigger than the framebuffer. However, it later refuses
10375      * to draw.
10376      */
10377     memset(&vp, 0, sizeof(vp));
10378     vp.X = 0;
10379     vp.Y = 0;
10380     vp.Width = 10000;
10381     vp.Height = 10000;
10382     vp.MinZ = 0.0;
10383     vp.MaxZ = 0.0;
10384     hr = IDirect3DDevice9_SetViewport(device, &vp);
10385     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10386
10387     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10388     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10389     hr = IDirect3DDevice9_BeginScene(device);
10390     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10391     if(SUCCEEDED(hr))
10392     {
10393         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10394         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10395         draw_failed = FAILED(hr);
10396         hr = IDirect3DDevice9_EndScene(device);
10397         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10398     }
10399
10400     if(!draw_failed)
10401     {
10402         color = getPixelColor(device, 158, 118);
10403         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10404         color = getPixelColor(device, 162, 118);
10405         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10406         color = getPixelColor(device, 158, 122);
10407         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10408         color = getPixelColor(device, 162, 122);
10409         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10410
10411         color = getPixelColor(device, 478, 358);
10412         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10413         color = getPixelColor(device, 482, 358);
10414         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10415         color = getPixelColor(device, 478, 362);
10416         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10417         color = getPixelColor(device, 482, 362);
10418         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10419     }
10420
10421     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10422     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10423
10424     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10425     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10426 }
10427
10428 /* This test tests depth clamping / clipping behaviour:
10429  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10430  *   minimum/maximum z value.
10431  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10432  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10433  *   - Pretransformed vertices behave the same as regular vertices.
10434  */
10435 static void depth_clamp_test(IDirect3DDevice9 *device)
10436 {
10437     const struct tvertex quad1[] =
10438     {
10439         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10440         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10441         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10442         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10443     };
10444     const struct tvertex quad2[] =
10445     {
10446         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10447         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10448         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10449         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10450     };
10451     const struct vertex quad3[] =
10452     {
10453         {-0.65, 0.55,  5.0f,      0xffffffff},
10454         {-0.35, 0.55,  5.0f,      0xffffffff},
10455         {-0.65, 0.15,  5.0f,      0xffffffff},
10456         {-0.35, 0.15,  5.0f,      0xffffffff},
10457     };
10458     const struct vertex quad4[] =
10459     {
10460         {-0.87, 0.83, 10.0f,      0xffffffff},
10461         {-0.65, 0.83, 10.0f,      0xffffffff},
10462         {-0.87, 0.55, 10.0f,      0xffffffff},
10463         {-0.65, 0.55, 10.0f,      0xffffffff},
10464     };
10465     const struct vertex quad5[] =
10466     {
10467         { -0.5,  0.5, 10.0f,      0xff14f914},
10468         {  0.5,  0.5, 10.0f,      0xff14f914},
10469         { -0.5, -0.5, 10.0f,      0xff14f914},
10470         {  0.5, -0.5, 10.0f,      0xff14f914},
10471     };
10472     const struct tvertex quad6[] =
10473     {
10474         {    0,  120, 10.0f, 1.0, 0xfff91414},
10475         {  640,  120, 10.0f, 1.0, 0xfff91414},
10476         {    0,  180, 10.0f, 1.0, 0xfff91414},
10477         {  640,  180, 10.0f, 1.0, 0xfff91414},
10478     };
10479
10480     D3DVIEWPORT9 vp;
10481     D3DCOLOR color;
10482     HRESULT hr;
10483
10484     vp.X = 0;
10485     vp.Y = 0;
10486     vp.Width = 640;
10487     vp.Height = 480;
10488     vp.MinZ = 0.0;
10489     vp.MaxZ = 7.5;
10490
10491     hr = IDirect3DDevice9_SetViewport(device, &vp);
10492     if(FAILED(hr))
10493     {
10494         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10495          * the tests because the 7.5 is just intended to show that it doesn't have
10496          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10497          * viewport and continue.
10498          */
10499         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10500         vp.MaxZ = 1.0;
10501         hr = IDirect3DDevice9_SetViewport(device, &vp);
10502     }
10503     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10504
10505     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10506     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10507
10508     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10509     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10510     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10511     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10512     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10513     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10514     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10515     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10516
10517     hr = IDirect3DDevice9_BeginScene(device);
10518     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10519
10520     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10521     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10522
10523     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10524     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10525     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10526     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10527
10528     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10529     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10530
10531     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10532     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10533     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10534     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10535
10536     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10537     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10538
10539     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10540     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10541
10542     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10543     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10544
10545     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10546     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10547
10548     hr = IDirect3DDevice9_EndScene(device);
10549     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10550
10551     color = getPixelColor(device, 75, 75);
10552     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10553     color = getPixelColor(device, 150, 150);
10554     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10555     color = getPixelColor(device, 320, 240);
10556     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10557     color = getPixelColor(device, 320, 330);
10558     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10559     color = getPixelColor(device, 320, 330);
10560     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10561
10562     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10563     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10564
10565     vp.MinZ = 0.0;
10566     vp.MaxZ = 1.0;
10567     hr = IDirect3DDevice9_SetViewport(device, &vp);
10568     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10569 }
10570
10571 static void depth_bounds_test(IDirect3DDevice9 *device)
10572 {
10573     const struct tvertex quad1[] =
10574     {
10575         {    0,    0, 0.0f, 1, 0xfff9e814},
10576         {  640,    0, 0.0f, 1, 0xfff9e814},
10577         {    0,  480, 1.0f, 1, 0xfff9e814},
10578         {  640,  480, 1.0f, 1, 0xfff9e814},
10579     };
10580     const struct tvertex quad2[] =
10581     {
10582         {    0,    0,  0.6f, 1, 0xff002b7f},
10583         {  640,    0,  0.6f, 1, 0xff002b7f},
10584         {    0,  480,  0.6f, 1, 0xff002b7f},
10585         {  640,  480,  0.6f, 1, 0xff002b7f},
10586     };
10587     const struct tvertex quad3[] =
10588     {
10589         {    0,  100, 0.6f, 1, 0xfff91414},
10590         {  640,  100, 0.6f, 1, 0xfff91414},
10591         {    0,  160, 0.6f, 1, 0xfff91414},
10592         {  640,  160, 0.6f, 1, 0xfff91414},
10593     };
10594
10595     union {
10596         DWORD d;
10597         float f;
10598     } tmpvalue;
10599
10600     IDirect3D9 *d3d = NULL;
10601     IDirect3DSurface9 *offscreen_surface = NULL;
10602     D3DCOLOR color;
10603     HRESULT hr;
10604
10605     IDirect3DDevice9_GetDirect3D(device, &d3d);
10606     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10607             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10608         skip("No NVDB (depth bounds test) support\n");
10609         IDirect3D9_Release(d3d);
10610         return;
10611     }
10612     IDirect3D9_Release(d3d);
10613
10614     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10615             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10616     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10617     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10618
10619     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10620     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10621
10622     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10623     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10624     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10625     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10626     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10627     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10628     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10629     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10630
10631
10632     hr = IDirect3DDevice9_BeginScene(device);
10633     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10634
10635     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10636     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10637
10638     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10639     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10640
10641     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10642     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10643
10644     tmpvalue.f = 0.625;
10645     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10646     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10647
10648     tmpvalue.f = 0.75;
10649     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10650     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10651
10652     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10653     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10654
10655     tmpvalue.f = 0.75;
10656     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10657     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10658
10659     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10660     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10661
10662     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10663     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10664
10665     hr = IDirect3DDevice9_EndScene(device);
10666     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10667
10668     color = getPixelColor(device, 150, 130);
10669     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10670     color = getPixelColor(device, 150, 200);
10671     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10672     color = getPixelColor(device, 150, 300-5);
10673     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10674     color = getPixelColor(device, 150, 300+5);
10675     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10676     color = getPixelColor(device, 150, 330);
10677     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10678     color = getPixelColor(device, 150, 360-5);
10679     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10680     color = getPixelColor(device, 150, 360+5);
10681     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10682
10683     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10684     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10685 }
10686
10687 static void depth_buffer_test(IDirect3DDevice9 *device)
10688 {
10689     static const struct vertex quad1[] =
10690     {
10691         { -1.0,  1.0, 0.33f, 0xff00ff00},
10692         {  1.0,  1.0, 0.33f, 0xff00ff00},
10693         { -1.0, -1.0, 0.33f, 0xff00ff00},
10694         {  1.0, -1.0, 0.33f, 0xff00ff00},
10695     };
10696     static const struct vertex quad2[] =
10697     {
10698         { -1.0,  1.0, 0.50f, 0xffff00ff},
10699         {  1.0,  1.0, 0.50f, 0xffff00ff},
10700         { -1.0, -1.0, 0.50f, 0xffff00ff},
10701         {  1.0, -1.0, 0.50f, 0xffff00ff},
10702     };
10703     static const struct vertex quad3[] =
10704     {
10705         { -1.0,  1.0, 0.66f, 0xffff0000},
10706         {  1.0,  1.0, 0.66f, 0xffff0000},
10707         { -1.0, -1.0, 0.66f, 0xffff0000},
10708         {  1.0, -1.0, 0.66f, 0xffff0000},
10709     };
10710     static const DWORD expected_colors[4][4] =
10711     {
10712         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10713         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10714         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10715         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10716     };
10717
10718     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10719     unsigned int i, j;
10720     D3DVIEWPORT9 vp;
10721     D3DCOLOR color;
10722     HRESULT hr;
10723
10724     vp.X = 0;
10725     vp.Y = 0;
10726     vp.Width = 640;
10727     vp.Height = 480;
10728     vp.MinZ = 0.0;
10729     vp.MaxZ = 1.0;
10730
10731     hr = IDirect3DDevice9_SetViewport(device, &vp);
10732     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10733
10734     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10735     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10736     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10737     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10738     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10739     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10740     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10741     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10742     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10743     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10744
10745     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10746     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10747     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10748             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10749     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10750     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10751             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10752     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10753     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10754             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10755     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10756
10757     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10758     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10759     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10760     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10761
10762     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10763     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10764     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10765     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10766
10767     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10768     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10769     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10770     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10771
10772     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10773     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10774     hr = IDirect3DDevice9_BeginScene(device);
10775     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10776     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10777     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10778     hr = IDirect3DDevice9_EndScene(device);
10779     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10780
10781     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10782     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10783     IDirect3DSurface9_Release(backbuffer);
10784     IDirect3DSurface9_Release(rt3);
10785     IDirect3DSurface9_Release(rt2);
10786     IDirect3DSurface9_Release(rt1);
10787
10788     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10789     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10790
10791     hr = IDirect3DDevice9_BeginScene(device);
10792     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10793     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10794     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10795     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10796     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10797     hr = IDirect3DDevice9_EndScene(device);
10798     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10799
10800     for (i = 0; i < 4; ++i)
10801     {
10802         for (j = 0; j < 4; ++j)
10803         {
10804             unsigned int x = 80 * ((2 * j) + 1);
10805             unsigned int y = 60 * ((2 * i) + 1);
10806             color = getPixelColor(device, x, y);
10807             ok(color_match(color, expected_colors[i][j], 0),
10808                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10809         }
10810     }
10811
10812     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10813     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10814 }
10815
10816 static void intz_test(IDirect3DDevice9 *device)
10817 {
10818     static const DWORD ps_code[] =
10819     {
10820         0xffff0200,                                                             /* ps_2_0                       */
10821         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
10822         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
10823         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
10824         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
10825         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
10826         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
10827         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
10828         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
10829         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
10830         0x0000ffff,                                                             /* end                          */
10831     };
10832     struct
10833     {
10834         float x, y, z;
10835         float s, t, p, q;
10836     }
10837     quad[] =
10838     {
10839         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
10840         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
10841         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
10842         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
10843     };
10844     struct
10845     {
10846         UINT x, y;
10847         D3DCOLOR color;
10848     }
10849     expected_colors[] =
10850     {
10851         {400,  60, D3DCOLOR_ARGB(0x00, 0x9f, 0xff, 0x00)},
10852         {560, 180, D3DCOLOR_ARGB(0x00, 0xdf, 0x55, 0x00)},
10853         {560, 300, D3DCOLOR_ARGB(0x00, 0xdf, 0x66, 0x00)},
10854         {400, 420, D3DCOLOR_ARGB(0x00, 0x9f, 0xb6, 0x00)},
10855         {240, 420, D3DCOLOR_ARGB(0x00, 0x60, 0x6d, 0x00)},
10856         { 80, 300, D3DCOLOR_ARGB(0x00, 0x20, 0x33, 0x00)},
10857         { 80, 180, D3DCOLOR_ARGB(0x00, 0x20, 0x55, 0x00)},
10858         {240,  60, D3DCOLOR_ARGB(0x00, 0x60, 0xff, 0x00)},
10859     };
10860
10861     IDirect3DSurface9 *original_ds, *original_rt, *rt;
10862     IDirect3DTexture9 *texture;
10863     IDirect3DPixelShader9 *ps;
10864     IDirect3DSurface9 *ds;
10865     IDirect3D9 *d3d9;
10866     D3DCAPS9 caps;
10867     HRESULT hr;
10868     UINT i;
10869
10870     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10871     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
10872     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
10873     {
10874         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
10875         return;
10876     }
10877
10878     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
10879     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
10880
10881     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10882             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
10883     if (FAILED(hr))
10884     {
10885         skip("No INTZ support, skipping INTZ test.\n");
10886         return;
10887     }
10888
10889     IDirect3D9_Release(d3d9);
10890
10891     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
10892     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10893     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
10894     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10895
10896     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
10897             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
10898     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
10899     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
10900             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
10901     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10902     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
10903     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
10904
10905     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
10906     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10907     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10908     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10909     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10910     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10911     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10912     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10913     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10914     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10915
10916     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10917     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10918     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10919     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10920     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10921     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10922     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10923     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10924     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10925     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10926
10927     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
10928     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
10929     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
10930     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10931     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10932     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10933     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10934     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10935
10936     /* Setup the depth/stencil surface. */
10937     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10938     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10939
10940     hr = IDirect3DDevice9_BeginScene(device);
10941     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10942     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10943     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10944     hr = IDirect3DDevice9_EndScene(device);
10945     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10946
10947     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
10948     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10949     IDirect3DSurface9_Release(ds);
10950     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
10951     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10952     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10953     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10954     hr = IDirect3DDevice9_SetPixelShader(device, ps);
10955     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10956
10957     /* Read the depth values back. */
10958     hr = IDirect3DDevice9_BeginScene(device);
10959     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10960     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10961     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10962     hr = IDirect3DDevice9_EndScene(device);
10963     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10964
10965     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
10966     {
10967         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
10968         ok(color_match(color, expected_colors[i].color, 1),
10969                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
10970                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
10971     }
10972
10973     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10974     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10975
10976     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
10977     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10978     IDirect3DSurface9_Release(original_ds);
10979     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10980     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10981     IDirect3DTexture9_Release(texture);
10982     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10983     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10984     IDirect3DPixelShader9_Release(ps);
10985
10986     IDirect3DSurface9_Release(original_rt);
10987     IDirect3DSurface9_Release(rt);
10988 }
10989
10990 static void shadow_test(IDirect3DDevice9 *device)
10991 {
10992     static const DWORD ps_code[] =
10993     {
10994         0xffff0200,                                                             /* ps_2_0                       */
10995         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
10996         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
10997         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
10998         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
10999         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11000         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11001         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11002         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11003         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11004         0x0000ffff,                                                             /* end                          */
11005     };
11006     struct
11007     {
11008         D3DFORMAT format;
11009         const char *name;
11010     }
11011     formats[] =
11012     {
11013         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11014         {D3DFMT_D32,            "D3DFMT_D32"},
11015         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11016         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11017         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11018         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11019         {D3DFMT_D16,            "D3DFMT_D16"},
11020         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11021         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11022     };
11023     struct
11024     {
11025         float x, y, z;
11026         float s, t, p, q;
11027     }
11028     quad[] =
11029     {
11030         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11031         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11032         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11033         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11034     };
11035     struct
11036     {
11037         UINT x, y;
11038         D3DCOLOR color;
11039     }
11040     expected_colors[] =
11041     {
11042         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11043         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11044         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11045         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11046         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11047         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11048         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11049         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11050     };
11051
11052     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11053     IDirect3DPixelShader9 *ps;
11054     IDirect3D9 *d3d9;
11055     D3DCAPS9 caps;
11056     HRESULT hr;
11057     UINT i;
11058
11059     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11060     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11061     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11062     {
11063         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11064         return;
11065     }
11066
11067     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11068     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11069     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11070     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11071     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11072     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11073
11074     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11075             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11076     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11077     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11078     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11079
11080     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11081     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11082     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11083     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11085     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11086     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11087     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11089     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11090
11091     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11092     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11093     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11094     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11095     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11096     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11097     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11098     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11099     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11100     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11101
11102     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11103     {
11104         D3DFORMAT format = formats[i].format;
11105         IDirect3DTexture9 *texture;
11106         IDirect3DSurface9 *ds;
11107         unsigned int j;
11108
11109         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11110                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11111         if (FAILED(hr)) continue;
11112
11113         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11114                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11115         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11116
11117         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11118         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11119
11120         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11121         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11122
11123         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11124         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11125
11126         IDirect3DDevice9_SetPixelShader(device, NULL);
11127         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11128
11129         /* Setup the depth/stencil surface. */
11130         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11131         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11132
11133         hr = IDirect3DDevice9_BeginScene(device);
11134         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11135         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11136         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11137         hr = IDirect3DDevice9_EndScene(device);
11138         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11139
11140         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11141         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11142         IDirect3DSurface9_Release(ds);
11143
11144         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11145         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11146
11147         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11148         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11149
11150         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11151         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11152
11153         /* Do the actual shadow mapping. */
11154         hr = IDirect3DDevice9_BeginScene(device);
11155         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11156         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11157         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11158         hr = IDirect3DDevice9_EndScene(device);
11159         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11160
11161         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11162         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11163         IDirect3DTexture9_Release(texture);
11164
11165         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11166         {
11167             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11168             ok(color_match(color, expected_colors[j].color, 0),
11169                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11170                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11171                     formats[i].name, color);
11172         }
11173
11174         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11175         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11176     }
11177
11178     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11179     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11180     IDirect3DPixelShader9_Release(ps);
11181
11182     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11183     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11184     IDirect3DSurface9_Release(original_ds);
11185
11186     IDirect3DSurface9_Release(original_rt);
11187     IDirect3DSurface9_Release(rt);
11188
11189     IDirect3D9_Release(d3d9);
11190 }
11191
11192 static void fp_special_test(IDirect3DDevice9 *device)
11193 {
11194     static const DWORD vs_header[] =
11195     {
11196         0xfffe0200,                                                             /* vs_2_0                       */
11197         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11198         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11199         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11200     };
11201
11202     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11203     static const DWORD vs_pow[] =
11204             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11205     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11206     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11207     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11208     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11209     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11210
11211     static const DWORD vs_footer[] =
11212     {
11213         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11214         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11215         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11216         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11217         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11218         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11219         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11220         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11221         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11222         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11223         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11224         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11225         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11226         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11227         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11228         0x0000ffff,                                                             /* end                          */
11229     };
11230
11231     static const struct
11232     {
11233         const char *name;
11234         const DWORD *ops;
11235         DWORD size;
11236         D3DCOLOR color1;
11237         D3DCOLOR color2;
11238     }
11239     vs_body[] =
11240     {
11241         /* The basic ideas here are:
11242          *     2.0 * +/-INF == +/-INF
11243          *     NAN != NAN
11244          *
11245          * The vertex shader value is written to the red component, with 0.0
11246          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11247          * result in 0x00. The pixel shader value is written to the green
11248          * component, but here 0.0 also results in 0x00. The actual value is
11249          * written to the blue component.
11250          *
11251          * There are at least two different ways for D3D implementations to
11252          * handle this. AMD seems to stick mostly to the D3D documentation,
11253          * and doesn't generate floating point specials in the first place.
11254          * Note that that doesn't just apply to functions like rcp and rsq,
11255          * but also basic mul, add, etc. nVidia seems to generate infinities,
11256          * but then clamp them before sending them to the interpolators. In
11257          * OpenGL these aren't clamped, and interpolating them generates NANs
11258          * in the fragment shader, unless flat shading is used (essentially
11259          * replicating the values instead of interpolating them).
11260          *
11261          * I can't currently explain the nVidia results for pow and nrm.
11262          * They're not specials in the vertex shader, but look like -INF in
11263          * the pixel shader. */
11264         {"log",     vs_log,     sizeof(vs_log),     0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
11265         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff /* +FLT_MAX */,  0x0000ff00 /* ???         */},
11266         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000 /*  0.0     */,  0x0000ff00 /* ???         */},
11267         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
11268         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000 /* -FLT_MAX */,  0x00ff0000 /* clamp(-INF) */},
11269         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
11270         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff /* +FLT_MAX */,  0x00ff00ff /* clamp(+INF) */},
11271     };
11272
11273     static const DWORD ps_code[] =
11274     {
11275         0xffff0200,                                                             /* ps_2_0                       */
11276         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11277         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11278         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11279         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11280         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11281         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11282         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11283         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11284         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11285         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11286         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11287         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11288         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11289         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11290         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11291         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11292         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11293         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11294         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11295         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11296         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11297         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11298         0x0000ffff,                                                             /* end                          */
11299     };
11300
11301     struct
11302     {
11303         float x, y, z;
11304         float s;
11305     }
11306     quad[] =
11307     {
11308         { -1.0f,  1.0f, 0.0f, 0.0f},
11309         {  1.0f,  1.0f, 1.0f, 0.0f},
11310         { -1.0f, -1.0f, 0.0f, 0.0f},
11311         {  1.0f, -1.0f, 1.0f, 0.0f},
11312     };
11313
11314     IDirect3DPixelShader9 *ps;
11315     UINT body_size = 0;
11316     DWORD *vs_code;
11317     D3DCAPS9 caps;
11318     HRESULT hr;
11319     UINT i;
11320
11321     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11322     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11323     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11324     {
11325         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11326         return;
11327     }
11328
11329     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11330     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11331
11332     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11333     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11334     IDirect3DDevice9_SetPixelShader(device, ps);
11335     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11336
11337     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11338     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11339
11340     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11341     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11342
11343     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11344     {
11345         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11346     }
11347
11348     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11349     memcpy(vs_code, vs_header, sizeof(vs_header));
11350
11351     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11352     {
11353         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11354         IDirect3DVertexShader9 *vs;
11355         D3DCOLOR color;
11356
11357         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11358         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11359         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11360
11361         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11362         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11363         IDirect3DDevice9_SetVertexShader(device, vs);
11364         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11365
11366         hr = IDirect3DDevice9_BeginScene(device);
11367         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11368         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11369         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11370         hr = IDirect3DDevice9_EndScene(device);
11371         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11372
11373         color = getPixelColor(device, 320, 240);
11374         ok(color_match(color, vs_body[i].color1, 1) || color_match(color, vs_body[i].color2, 1),
11375                 "Expected color 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11376                 vs_body[i].color1, vs_body[i].color2, vs_body[i].name, color);
11377
11378         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11379         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11380
11381         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11382         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11383         IDirect3DVertexShader9_Release(vs);
11384     }
11385
11386     HeapFree(GetProcessHeap(), 0, vs_code);
11387
11388     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11389     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11390     IDirect3DPixelShader9_Release(ps);
11391 }
11392
11393 START_TEST(visual)
11394 {
11395     IDirect3DDevice9 *device_ptr;
11396     D3DCAPS9 caps;
11397     HRESULT hr;
11398     DWORD color;
11399
11400     d3d9_handle = LoadLibraryA("d3d9.dll");
11401     if (!d3d9_handle)
11402     {
11403         skip("Could not load d3d9.dll\n");
11404         return;
11405     }
11406
11407     device_ptr = init_d3d9();
11408     if (!device_ptr)
11409     {
11410         skip("Creating the device failed\n");
11411         return;
11412     }
11413
11414     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11415
11416     /* Check for the reliability of the returned data */
11417     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11418     if(FAILED(hr))
11419     {
11420         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11421         goto cleanup;
11422     }
11423
11424     color = getPixelColor(device_ptr, 1, 1);
11425     if(color !=0x00ff0000)
11426     {
11427         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11428         goto cleanup;
11429     }
11430     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11431
11432     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11433     if(FAILED(hr))
11434     {
11435         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11436         goto cleanup;
11437     }
11438
11439     color = getPixelColor(device_ptr, 639, 479);
11440     if(color != 0x0000ddee)
11441     {
11442         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11443         goto cleanup;
11444     }
11445     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11446
11447     /* Now execute the real tests */
11448     depth_clamp_test(device_ptr);
11449     stretchrect_test(device_ptr);
11450     lighting_test(device_ptr);
11451     clear_test(device_ptr);
11452     color_fill_test(device_ptr);
11453     fog_test(device_ptr);
11454     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11455     {
11456         test_cube_wrap(device_ptr);
11457     } else {
11458         skip("No cube texture support\n");
11459     }
11460     z_range_test(device_ptr);
11461     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11462     {
11463         maxmip_test(device_ptr);
11464     }
11465     else
11466     {
11467         skip("No mipmap support\n");
11468     }
11469     offscreen_test(device_ptr);
11470     alpha_test(device_ptr);
11471     shademode_test(device_ptr);
11472     srgbtexture_test(device_ptr);
11473     release_buffer_test(device_ptr);
11474     float_texture_test(device_ptr);
11475     g16r16_texture_test(device_ptr);
11476     pixelshader_blending_test(device_ptr);
11477     texture_transform_flags_test(device_ptr);
11478     autogen_mipmap_test(device_ptr);
11479     fixed_function_decl_test(device_ptr);
11480     conditional_np2_repeat_test(device_ptr);
11481     fixed_function_bumpmap_test(device_ptr);
11482     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11483         stencil_cull_test(device_ptr);
11484     } else {
11485         skip("No two sided stencil support\n");
11486     }
11487     pointsize_test(device_ptr);
11488     tssargtemp_test(device_ptr);
11489     np2_stretch_rect_test(device_ptr);
11490     yuv_color_test(device_ptr);
11491     zwriteenable_test(device_ptr);
11492     alphatest_test(device_ptr);
11493     viewport_test(device_ptr);
11494
11495     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11496     {
11497         test_constant_clamp_vs(device_ptr);
11498         test_compare_instructions(device_ptr);
11499     }
11500     else skip("No vs_1_1 support\n");
11501
11502     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11503     {
11504         test_mova(device_ptr);
11505         loop_index_test(device_ptr);
11506         sincos_test(device_ptr);
11507         sgn_test(device_ptr);
11508         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11509             test_vshader_input(device_ptr);
11510             test_vshader_float16(device_ptr);
11511             stream_test(device_ptr);
11512         } else {
11513             skip("No vs_3_0 support\n");
11514         }
11515     }
11516     else skip("No vs_2_0 support\n");
11517
11518     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11519     {
11520         fog_with_shader_test(device_ptr);
11521     }
11522     else skip("No vs_1_1 and ps_1_1 support\n");
11523
11524     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11525     {
11526         texbem_test(device_ptr);
11527         texdepth_test(device_ptr);
11528         texkill_test(device_ptr);
11529         x8l8v8u8_test(device_ptr);
11530         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11531             constant_clamp_ps_test(device_ptr);
11532             cnd_test(device_ptr);
11533             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11534                 dp2add_ps_test(device_ptr);
11535                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11536                     nested_loop_test(device_ptr);
11537                     fixed_function_varying_test(device_ptr);
11538                     vFace_register_test(device_ptr);
11539                     vpos_register_test(device_ptr);
11540                     multiple_rendertargets_test(device_ptr);
11541                 } else {
11542                     skip("No ps_3_0 or vs_3_0 support\n");
11543                 }
11544             } else {
11545                 skip("No ps_2_0 support\n");
11546             }
11547         }
11548     }
11549     else skip("No ps_1_1 support\n");
11550
11551     texop_test(device_ptr);
11552     texop_range_test(device_ptr);
11553     alphareplicate_test(device_ptr);
11554     dp3_alpha_test(device_ptr);
11555     depth_buffer_test(device_ptr);
11556     intz_test(device_ptr);
11557     shadow_test(device_ptr);
11558     fp_special_test(device_ptr);
11559     depth_bounds_test(device_ptr);
11560
11561 cleanup:
11562     if(device_ptr) {
11563         D3DPRESENT_PARAMETERS present_parameters;
11564         IDirect3DSwapChain9 *swapchain;
11565         ULONG ref;
11566
11567         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11568         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11569         IDirect3DSwapChain9_Release(swapchain);
11570         ref = IDirect3DDevice9_Release(device_ptr);
11571         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11572         DestroyWindow(present_parameters.hDeviceWindow);
11573     }
11574 }