mshtml: Added IHTMLWindow2::focus implementation.
[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_CreateOffscreenPlainSurface(device, 640, 480,
114             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
115     if (FAILED(hr) || !surf)
116     {
117         trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
118         return 0xdeadbeef;
119     }
120
121     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
122     if(FAILED(hr))
123     {
124         trace("Can't get the render target, hr=%08x\n", hr);
125         ret = 0xdeadbeed;
126         goto out;
127     }
128
129     hr = IDirect3DDevice9_GetRenderTargetData(device, target, surf);
130     if (FAILED(hr))
131     {
132         trace("Can't read the render target data, hr=%08x\n", hr);
133         ret = 0xdeadbeec;
134         goto out;
135     }
136
137     hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
138     if(FAILED(hr))
139     {
140         trace("Can't lock the offscreen surface, hr=%08x\n", hr);
141         ret = 0xdeadbeeb;
142         goto out;
143     }
144
145     /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
146      * really important for these tests
147      */
148     ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
149     hr = IDirect3DSurface9_UnlockRect(surf);
150     if(FAILED(hr))
151     {
152         trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
153     }
154
155 out:
156     if(target) IDirect3DSurface9_Release(target);
157     if(surf) IDirect3DSurface9_Release(surf);
158     return ret;
159 }
160
161 static IDirect3DDevice9 *init_d3d9(void)
162 {
163     IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
164     IDirect3D9 *d3d9_ptr = 0;
165     IDirect3DDevice9 *device_ptr = 0;
166     D3DPRESENT_PARAMETERS present_parameters;
167     HRESULT hr;
168     D3DADAPTER_IDENTIFIER9 identifier;
169
170     d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
171     ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
172     if (!d3d9_create) return NULL;
173
174     d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
175     if (!d3d9_ptr)
176     {
177         skip("could not create D3D9\n");
178         return NULL;
179     }
180
181     ZeroMemory(&present_parameters, sizeof(present_parameters));
182     present_parameters.Windowed = TRUE;
183     present_parameters.hDeviceWindow = create_window();
184     present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
185     present_parameters.BackBufferWidth = 640;
186     present_parameters.BackBufferHeight = 480;
187     present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
188     present_parameters.EnableAutoDepthStencil = TRUE;
189     present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
190
191     memset(&identifier, 0, sizeof(identifier));
192     hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
193     ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
194     trace("Driver string: \"%s\"\n", identifier.Driver);
195     trace("Description string: \"%s\"\n", identifier.Description);
196     ok(identifier.Description[0] != '\0', "Empty driver description\n");
197     trace("Device name string: \"%s\"\n", identifier.DeviceName);
198     ok(identifier.DeviceName[0]  != '\0', "Empty device name\n");
199     trace("Driver version %d.%d.%d.%d\n",
200           HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
201           HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
202
203     hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
204     if(FAILED(hr)) {
205         present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
206         hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
207         if(FAILED(hr)) {
208             hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
209         }
210     }
211     ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
212
213     return device_ptr;
214 }
215
216 struct vertex
217 {
218     float x, y, z;
219     DWORD diffuse;
220 };
221
222 struct tvertex
223 {
224     float x, y, z, rhw;
225     DWORD diffuse;
226 };
227
228 struct nvertex
229 {
230     float x, y, z;
231     float nx, ny, nz;
232     DWORD diffuse;
233 };
234
235 static void lighting_test(IDirect3DDevice9 *device)
236 {
237     HRESULT hr;
238     DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
239     DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
240     DWORD color;
241     D3DMATERIAL9 material, old_material;
242     DWORD cop, carg;
243
244     float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
245                       0.0f, 1.0f, 0.0f, 0.0f,
246                       0.0f, 0.0f, 1.0f, 0.0f,
247                       0.0f, 0.0f, 0.0f, 1.0f };
248
249     struct vertex unlitquad[] =
250     {
251         {-1.0f, -1.0f,   0.1f,                          0xffff0000},
252         {-1.0f,  0.0f,   0.1f,                          0xffff0000},
253         { 0.0f,  0.0f,   0.1f,                          0xffff0000},
254         { 0.0f, -1.0f,   0.1f,                          0xffff0000},
255     };
256     struct vertex litquad[] =
257     {
258         {-1.0f,  0.0f,   0.1f,                          0xff00ff00},
259         {-1.0f,  1.0f,   0.1f,                          0xff00ff00},
260         { 0.0f,  1.0f,   0.1f,                          0xff00ff00},
261         { 0.0f,  0.0f,   0.1f,                          0xff00ff00},
262     };
263     struct nvertex unlitnquad[] =
264     {
265         { 0.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
266         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
267         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
268         { 1.0f, -1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xff0000ff},
269     };
270     struct nvertex litnquad[] =
271     {
272         { 0.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
273         { 0.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
274         { 1.0f,  1.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
275         { 1.0f,  0.0f,   0.1f,  1.0f,   1.0f,   1.0f,   0xffffff00},
276     };
277     WORD Indices[] = {0, 1, 2, 2, 3, 0};
278
279     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
280     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
281
282     /* Setup some states that may cause issues */
283     hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
284     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
285     hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
286     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
287     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
288     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
289     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
290     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
291     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
292     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
293     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
294     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
295     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
296     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
297     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
298     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
299     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
300     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
301     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
302     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
303     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
304     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
305     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
306     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
307
308     hr = IDirect3DDevice9_SetFVF(device, 0);
309     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
310
311     hr = IDirect3DDevice9_SetFVF(device, fvf);
312     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
313
314     hr = IDirect3DDevice9_BeginScene(device);
315     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
316     if(hr == D3D_OK)
317     {
318         /* No lights are defined... That means, lit vertices should be entirely black */
319         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
320         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
321         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
322                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
323         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324
325         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
326         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
327         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
328                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
329         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330
331         hr = IDirect3DDevice9_SetFVF(device, nfvf);
332         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
333
334         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
335         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
336         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
337                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
338         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
339
340         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
341         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
342         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
343                                                     2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
344         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
345
346         IDirect3DDevice9_EndScene(device);
347         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
348     }
349
350     color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
351     ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
352     color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
353     ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
354     color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
355     ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
356     color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
357     ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
358
359     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
360
361     hr = IDirect3DDevice9_GetMaterial(device, &old_material);
362     ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
363     memset(&material, 0, sizeof(material));
364     material.Diffuse.r = 0.0;
365     material.Diffuse.g = 0.0;
366     material.Diffuse.b = 0.0;
367     material.Diffuse.a = 1.0;
368     material.Ambient.r = 0.0;
369     material.Ambient.g = 0.0;
370     material.Ambient.b = 0.0;
371     material.Ambient.a = 0.0;
372     material.Specular.r = 0.0;
373     material.Specular.g = 0.0;
374     material.Specular.b = 0.0;
375     material.Specular.a = 0.0;
376     material.Emissive.r = 0.0;
377     material.Emissive.g = 0.0;
378     material.Emissive.b = 0.0;
379     material.Emissive.a = 0.0;
380     material.Power = 0.0;
381     IDirect3DDevice9_SetMaterial(device, &material);
382     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
383
384     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
385     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
386     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
387     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
388
389     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
390     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
391     hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
392     ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
393     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
394     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
395     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
396     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
397
398     hr = IDirect3DDevice9_BeginScene(device);
399     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
400     if(SUCCEEDED(hr)) {
401         struct vertex lighting_test[] = {
402             {-1.0,   -1.0,   0.1,    0x8000ff00},
403             { 1.0,   -1.0,   0.1,    0x80000000},
404             {-1.0,    1.0,   0.1,    0x8000ff00},
405             { 1.0,    1.0,   0.1,    0x80000000}
406         };
407         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
408         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
409         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
410         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
411
412         hr = IDirect3DDevice9_EndScene(device);
413         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
414     }
415
416     color = getPixelColor(device, 320, 240);
417     ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
418     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419
420     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
421     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
422     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
423     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
424     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
425     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
426     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
427     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
428     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
429     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
430     hr = IDirect3DDevice9_SetMaterial(device, &old_material);
431     ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
432 }
433
434 static void clear_test(IDirect3DDevice9 *device)
435 {
436     /* Tests the correctness of clearing parameters */
437     HRESULT hr;
438     D3DRECT rect[2];
439     D3DRECT rect_negneg;
440     DWORD color;
441     D3DVIEWPORT9 old_vp, vp;
442     RECT scissor;
443     DWORD oldColorWrite;
444     BOOL invalid_clear_failed = FALSE;
445
446     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
448
449     /* Positive x, negative y */
450     rect[0].x1 = 0;
451     rect[0].y1 = 480;
452     rect[0].x2 = 320;
453     rect[0].y2 = 240;
454
455     /* Positive x, positive y */
456     rect[1].x1 = 0;
457     rect[1].y1 = 0;
458     rect[1].x2 = 320;
459     rect[1].y2 = 240;
460     /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
461      * returns D3D_OK, but ignores the rectangle silently
462      */
463     hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
464     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
465     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
466
467     /* negative x, negative y */
468     rect_negneg.x1 = 640;
469     rect_negneg.y1 = 240;
470     rect_negneg.x2 = 320;
471     rect_negneg.y2 = 0;
472     hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
473     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
474     if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
475
476     color = getPixelColor(device, 160, 360); /* lower left quad */
477     ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
478     color = getPixelColor(device, 160, 120); /* upper left quad */
479     if(invalid_clear_failed) {
480         /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
481         ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
482     } else {
483         /* If the negative rectangle was dropped silently, the correct ones are cleared */
484         ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
485     }
486     color = getPixelColor(device, 480, 360); /* lower right quad  */
487     ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
488     color = getPixelColor(device, 480, 120); /* upper right quad */
489     ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
490
491     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
492
493     /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
494      * clear the red quad in the top left part of the render target. For some reason it
495      * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
496      * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
497      * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
498      * pick some obvious value
499      */
500     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
501     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
502
503     /* Test how the viewport affects clears */
504     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
505     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
506     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
507     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
508
509     vp.X = 160;
510     vp.Y = 120;
511     vp.Width = 160;
512     vp.Height = 120;
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     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
518     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
519
520     vp.X = 320;
521     vp.Y = 240;
522     vp.Width = 320;
523     vp.Height = 240;
524     vp.MinZ = 0.0;
525     vp.MaxZ = 1.0;
526     hr = IDirect3DDevice9_SetViewport(device, &vp);
527     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
528     rect[0].x1 = 160;
529     rect[0].y1 = 120;
530     rect[0].x2 = 480;
531     rect[0].y2 = 360;
532     hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
533     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
534
535     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
536     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
537
538     color = getPixelColor(device, 158, 118);
539     ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
540     color = getPixelColor(device, 162, 118);
541     ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
542     color = getPixelColor(device, 158, 122);
543     ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
544     color = getPixelColor(device, 162, 122);
545     ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
546
547     color = getPixelColor(device, 318, 238);
548     ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
549     color = getPixelColor(device, 322, 238);
550     ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
551     color = getPixelColor(device, 318, 242);
552     ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
553     color = getPixelColor(device, 322, 242);
554     ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
555
556     color = getPixelColor(device, 478, 358);
557     ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
558     color = getPixelColor(device, 482, 358);
559     ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
560     color = getPixelColor(device, 478, 362);
561     ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
562     color = getPixelColor(device, 482, 362);
563     ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
564
565     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
566
567     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
568     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
569
570     scissor.left = 160;
571     scissor.right = 480;
572     scissor.top = 120;
573     scissor.bottom = 360;
574     hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
575     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
576     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
577     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
578
579     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
580     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
581     hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
582     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
583
584     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
585     ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
586
587     color = getPixelColor(device, 158, 118);
588     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
589     color = getPixelColor(device, 162, 118);
590     ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
591     color = getPixelColor(device, 158, 122);
592     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
593     color = getPixelColor(device, 162, 122);
594     ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
595
596     color = getPixelColor(device, 158, 358);
597     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
598     color = getPixelColor(device, 162, 358);
599     ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
600     color = getPixelColor(device, 158, 358);
601     ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
602     color = getPixelColor(device, 162, 362);
603     ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
604
605     color = getPixelColor(device, 478, 118);
606     ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
607     color = getPixelColor(device, 478, 122);
608     ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
609     color = getPixelColor(device, 482, 122);
610     ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
611     color = getPixelColor(device, 482, 358);
612     ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
613
614     color = getPixelColor(device, 478, 358);
615     ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
616     color = getPixelColor(device, 478, 362);
617     ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
618     color = getPixelColor(device, 482, 358);
619     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
620     color = getPixelColor(device, 482, 362);
621     ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
622
623     color = getPixelColor(device, 318, 238);
624     ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
625     color = getPixelColor(device, 318, 242);
626     ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
627     color = getPixelColor(device, 322, 238);
628     ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
629     color = getPixelColor(device, 322, 242);
630     ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
631
632     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
633
634     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
635     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
636     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
637     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
638
639     /* Same nvidia windows driver trouble with white clears as earlier in the same test */
640     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
641     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
642
643     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
644     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
645
646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
647     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
648
649     /* Colorwriteenable does not affect the clear */
650     color = getPixelColor(device, 320, 240);
651     ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
652
653     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
654 }
655
656 static void color_fill_test(IDirect3DDevice9 *device)
657 {
658     HRESULT hr;
659     IDirect3DSurface9 *backbuffer = NULL;
660     IDirect3DSurface9 *rt_surface = NULL;
661     IDirect3DSurface9 *offscreen_surface = NULL;
662     DWORD fill_color, color;
663
664     /* Test ColorFill on a the backbuffer (should pass) */
665     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
666     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
667     if(backbuffer)
668     {
669         fill_color = 0x112233;
670         hr = IDirect3DDevice9_ColorFill(device, backbuffer, NULL, fill_color);
671         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
672
673         color = getPixelColor(device, 0, 0);
674         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
675
676         IDirect3DSurface9_Release(backbuffer);
677     }
678
679     /* Test ColorFill on a render target surface (should pass) */
680     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt_surface, NULL );
681     ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
682     if(rt_surface)
683     {
684         fill_color = 0x445566;
685         hr = IDirect3DDevice9_ColorFill(device, rt_surface, NULL, fill_color);
686         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
687
688         color = getPixelColorFromSurface(rt_surface, 0, 0);
689         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
690
691         IDirect3DSurface9_Release(rt_surface);
692     }
693
694     /* Test ColorFill on a offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
695     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
696             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen_surface, NULL);
697     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
698     if(offscreen_surface)
699     {
700         fill_color = 0x778899;
701         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, fill_color);
702         ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
703
704         color = getPixelColorFromSurface(offscreen_surface, 0, 0);
705         ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
706
707         IDirect3DSurface9_Release(offscreen_surface);
708     }
709
710     /* Try ColorFill on a offscreen surface in sysmem (should fail) */
711     offscreen_surface = NULL;
712     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
713             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, NULL);
714     ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
715     if(offscreen_surface)
716     {
717         hr = IDirect3DDevice9_ColorFill(device, offscreen_surface, NULL, 0);
718         ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
719
720         IDirect3DSurface9_Release(offscreen_surface);
721     }
722 }
723
724 typedef struct {
725     float in[4];
726     DWORD out;
727 } test_data_t;
728
729 /*
730  *  c7      mova    ARGB            mov     ARGB
731  * -2.4     -2      0x00ffff00      -3      0x00ff0000
732  * -1.6     -2      0x00ffff00      -2      0x00ffff00
733  * -0.4      0      0x0000ffff      -1      0x0000ff00
734  *  0.4      0      0x0000ffff       0      0x0000ffff
735  *  1.6      2      0x00ff00ff       1      0x000000ff
736  *  2.4      2      0x00ff00ff       2      0x00ff00ff
737  */
738 static void test_mova(IDirect3DDevice9 *device)
739 {
740     static const DWORD mova_test[] = {
741         0xfffe0200,                                                             /* vs_2_0                       */
742         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
743         0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
744         0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
745         0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
746         0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
747         0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
748         0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
749         0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
750         0x0200002e, 0xb0010000, 0xa0000007,                                     /* mova a0.x, c7.x              */
751         0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000,                         /* mov oD0, c[a0.x + 3]         */
752         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
753         0x0000ffff                                                              /* END                          */
754     };
755     static const DWORD mov_test[] = {
756         0xfffe0101,                                                             /* vs_1_1                       */
757         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
758         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0   */
759         0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0   */
760         0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0   */
761         0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0   */
762         0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0   */
763         0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0   */
764         0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0   */
765         0x00000001, 0xb0010000, 0xa0000007,                                     /* mov a0.x, c7.x               */
766         0x00000001, 0xd00f0000, 0xa0e42003,                                     /* mov oD0, c[a0.x + 3]         */
767         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
768         0x0000ffff                                                              /* END                          */
769     };
770
771     static const test_data_t test_data[2][6] = {
772         {
773             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
774             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
775             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
776             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
777             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
778             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
779         },
780         {
781             {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
782             {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
783             {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
784             {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
785             {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
786             {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
787         }
788     };
789
790     static const float quad[][3] = {
791         {-1.0f, -1.0f, 0.0f},
792         {-1.0f,  1.0f, 0.0f},
793         { 1.0f, -1.0f, 0.0f},
794         { 1.0f,  1.0f, 0.0f},
795     };
796
797     static const D3DVERTEXELEMENT9 decl_elements[] = {
798         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
799         D3DDECL_END()
800     };
801
802     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
803     IDirect3DVertexShader9 *mova_shader = NULL;
804     IDirect3DVertexShader9 *mov_shader = NULL;
805     HRESULT hr;
806     UINT i, j;
807
808     hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
809     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
810     hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
811     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
812     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
813     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
814     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
815     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
816
817     hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
818     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
819     for(j = 0; j < 2; ++j)
820     {
821         for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
822         {
823             DWORD color;
824
825             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
826             ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
827
828             hr = IDirect3DDevice9_BeginScene(device);
829             ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
830
831             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
832             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
833
834             hr = IDirect3DDevice9_EndScene(device);
835             ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
836
837             color = getPixelColor(device, 320, 240);
838             ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
839                test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
840
841             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
842             ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
843
844             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
845             ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
846         }
847         hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
848         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
849     }
850
851     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
852     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
853
854     IDirect3DVertexDeclaration9_Release(vertex_declaration);
855     IDirect3DVertexShader9_Release(mova_shader);
856     IDirect3DVertexShader9_Release(mov_shader);
857 }
858
859 struct sVertex {
860     float x, y, z;
861     DWORD diffuse;
862     DWORD specular;
863 };
864
865 struct sVertexT {
866     float x, y, z, rhw;
867     DWORD diffuse;
868     DWORD specular;
869 };
870
871 static void fog_test(IDirect3DDevice9 *device)
872 {
873     HRESULT hr;
874     D3DCOLOR color;
875     float start = 0.0f, end = 1.0f;
876     D3DCAPS9 caps;
877     int i;
878
879     /* Gets full z based fog with linear fog, no fog with specular color */
880     struct sVertex unstransformed_1[] = {
881         {-1,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
882         {-1,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
883         { 0,     0,   0.1f,         0xFFFF0000,     0xFF000000  },
884         { 0,    -1,   0.1f,         0xFFFF0000,     0xFF000000  },
885     };
886     /* Ok, I am too lazy to deal with transform matrices */
887     struct sVertex unstransformed_2[] = {
888         {-1,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
889         {-1,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
890         { 0,     1,   1.0f,         0xFFFF0000,     0xFF000000  },
891         { 0,     0,   1.0f,         0xFFFF0000,     0xFF000000  },
892     };
893     /* Untransformed ones. Give them a different diffuse color to make the test look
894      * nicer. It also makes making sure that they are drawn correctly easier.
895      */
896     struct sVertexT transformed_1[] = {
897         {320,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
898         {640,    0,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
899         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
900         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
901     };
902     struct sVertexT transformed_2[] = {
903         {320,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
904         {640,  240,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
905         {640,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
906         {320,  480,   1.0f, 1.0f,   0xFFFFFF00,     0xFF000000  },
907     };
908     struct vertex rev_fog_quads[] = {
909        {-1.0,   -1.0,   0.1,    0x000000ff},
910        {-1.0,    0.0,   0.1,    0x000000ff},
911        { 0.0,    0.0,   0.1,    0x000000ff},
912        { 0.0,   -1.0,   0.1,    0x000000ff},
913
914        { 0.0,   -1.0,   0.9,    0x000000ff},
915        { 0.0,    0.0,   0.9,    0x000000ff},
916        { 1.0,    0.0,   0.9,    0x000000ff},
917        { 1.0,   -1.0,   0.9,    0x000000ff},
918
919        { 0.0,    0.0,   0.4,    0x000000ff},
920        { 0.0,    1.0,   0.4,    0x000000ff},
921        { 1.0,    1.0,   0.4,    0x000000ff},
922        { 1.0,    0.0,   0.4,    0x000000ff},
923
924        {-1.0,    0.0,   0.7,    0x000000ff},
925        {-1.0,    1.0,   0.7,    0x000000ff},
926        { 0.0,    1.0,   0.7,    0x000000ff},
927        { 0.0,    0.0,   0.7,    0x000000ff},
928     };
929     WORD Indices[] = {0, 1, 2, 2, 3, 0};
930
931     memset(&caps, 0, sizeof(caps));
932     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
933     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
934     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
935     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
936
937     /* Setup initial states: No lighting, fog on, fog color */
938     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
939     ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
940     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
941     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
942     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
943     ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
944
945     /* First test: Both table fog and vertex fog off */
946     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
947     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
948     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
949     ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
950
951     /* Start = 0, end = 1. Should be default, but set them */
952     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
953     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
954     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
955     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
956
957     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
958     {
959         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
960         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
961         /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
962         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
963                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
964                                                      sizeof(unstransformed_1[0]));
965         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
966
967         /* That makes it use the Z value */
968         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
969         ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
970         /* Untransformed, vertex fog != none (or table fog != none):
971          * Use the Z value as input into the equation
972          */
973         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
974                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
975                                                      sizeof(unstransformed_1[0]));
976         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
977
978         /* transformed verts */
979         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
980         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
981         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
982         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
983                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
984                                                      sizeof(transformed_1[0]));
985         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
986
987         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
988         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
989         /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
990          * equation
991          */
992         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
993                                                      2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
994                                                      sizeof(transformed_2[0]));
995         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
996
997         hr = IDirect3DDevice9_EndScene(device);
998         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
999     }
1000     else
1001     {
1002         ok(FALSE, "BeginScene failed\n");
1003     }
1004
1005     color = getPixelColor(device, 160, 360);
1006     ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1007     color = getPixelColor(device, 160, 120);
1008     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1009     color = getPixelColor(device, 480, 120);
1010     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1011     if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1012     {
1013         color = getPixelColor(device, 480, 360);
1014         ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1015     }
1016     else
1017     {
1018         /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1019          * The settings above result in no fogging with vertex fog
1020          */
1021         color = getPixelColor(device, 480, 120);
1022         ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1023         trace("Info: Table fog not supported by this device\n");
1024     }
1025     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1026
1027     /* Now test the special case fogstart == fogend */
1028     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1029     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1030
1031     if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
1032     {
1033         start = 512;
1034         end = 512;
1035         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1036         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1037         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1038         ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1039
1040         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1041         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1042         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1043         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1044         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1045         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1046
1047         /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
1048          * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
1049          * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
1050          * The third transformed quad remains unfogged because the fogcoords are read from the specular
1051          * color and has fixed fogstart and fogend.
1052          */
1053         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1054                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
1055                 sizeof(unstransformed_1[0]));
1056         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1057         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1058                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
1059                 sizeof(unstransformed_1[0]));
1060         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1061
1062         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1063         ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
1064         /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
1065         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1066                 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
1067                 sizeof(transformed_1[0]));
1068         ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
1069
1070         hr = IDirect3DDevice9_EndScene(device);
1071         ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1072     }
1073     else
1074     {
1075         ok(FALSE, "BeginScene failed\n");
1076     }
1077     color = getPixelColor(device, 160, 360);
1078     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1079     color = getPixelColor(device, 160, 120);
1080     ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1081     color = getPixelColor(device, 480, 120);
1082     ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1083     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1084
1085     /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1086      * but without shaders it seems to work everywhere
1087      */
1088     end = 0.2;
1089     start = 0.8;
1090     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1091     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1092     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1093     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1094     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1095     ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1096
1097     /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1098      * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1099      * so skip this for now
1100      */
1101     for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1102         const char *mode = (i ? "table" : "vertex");
1103         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1104         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1105         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1106         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1107         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1108         ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1109         hr = IDirect3DDevice9_BeginScene(device);
1110         ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1111         if(SUCCEEDED(hr)) {
1112             WORD Indices2[] = { 0,  1,  2,  2,  3, 0,
1113                                 4,  5,  6,  6,  7, 4,
1114                                 8,  9, 10, 10, 11, 8,
1115                             12, 13, 14, 14, 15, 12};
1116
1117             hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1118                     16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1119                     sizeof(rev_fog_quads[0]));
1120             ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
1121
1122             hr = IDirect3DDevice9_EndScene(device);
1123             ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1124         }
1125         color = getPixelColor(device, 160, 360);
1126         ok(color_match(color, 0x0000ff00, 1),
1127                 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1128
1129         color = getPixelColor(device, 160, 120);
1130         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1131                 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1132
1133         color = getPixelColor(device, 480, 120);
1134         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1135                 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1136
1137         color = getPixelColor(device, 480, 360);
1138         ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1139
1140         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1141
1142         if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1143             skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1144             break;
1145         }
1146     }
1147     /* Turn off the fog master switch to avoid confusing other tests */
1148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1149     ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1150     start = 0.0;
1151     end = 1.0;
1152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1153     ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1155     ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1156     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1157     ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1158     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1159     ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1160 }
1161
1162 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1163  * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1164  * regardless of the actual addressing mode set. The way this test works is
1165  * that we sample in one of the corners of the cubemap with filtering enabled,
1166  * and check the interpolated color. There are essentially two reasonable
1167  * things an implementation can do: Either pick one of the faces and
1168  * interpolate the edge texel with itself (i.e., clamp within the face), or
1169  * interpolate between the edge texels of the three involved faces. It should
1170  * never involve the border color or the other side (texcoord wrapping) of a
1171  * face in the interpolation. */
1172 static void test_cube_wrap(IDirect3DDevice9 *device)
1173 {
1174     static const float quad[][6] = {
1175         {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1176         {-1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1177         { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1178         { 1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1179     };
1180
1181     static const D3DVERTEXELEMENT9 decl_elements[] = {
1182         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1183         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1184         D3DDECL_END()
1185     };
1186
1187     static const struct {
1188         D3DTEXTUREADDRESS mode;
1189         const char *name;
1190     } address_modes[] = {
1191         {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1192         {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1193         {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1194         {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1195         {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1196     };
1197
1198     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1199     IDirect3DCubeTexture9 *texture = NULL;
1200     IDirect3DSurface9 *surface = NULL;
1201     IDirect3DSurface9 *face_surface;
1202     D3DLOCKED_RECT locked_rect;
1203     HRESULT hr;
1204     UINT x;
1205     INT y, face;
1206
1207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1208     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1209     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1210     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1211
1212     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1213             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1214     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1215
1216     hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1217             D3DPOOL_DEFAULT, &texture, NULL);
1218     ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1219
1220     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1221     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1222
1223     for (y = 0; y < 128; ++y)
1224     {
1225         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1226         for (x = 0; x < 64; ++x)
1227         {
1228             *ptr++ = 0xff0000ff;
1229         }
1230         for (x = 64; x < 128; ++x)
1231         {
1232             *ptr++ = 0xffff0000;
1233         }
1234     }
1235
1236     hr = IDirect3DSurface9_UnlockRect(surface);
1237     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1238
1239     hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
1240     ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1241
1242     hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1243     ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1244
1245     IDirect3DSurface9_Release(face_surface);
1246
1247     hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1248     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1249
1250     for (y = 0; y < 128; ++y)
1251     {
1252         DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1253         for (x = 0; x < 64; ++x)
1254         {
1255             *ptr++ = 0xffff0000;
1256         }
1257         for (x = 64; x < 128; ++x)
1258         {
1259             *ptr++ = 0xff0000ff;
1260         }
1261     }
1262
1263     hr = IDirect3DSurface9_UnlockRect(surface);
1264     ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1265
1266     /* Create cube faces */
1267     for (face = 1; face < 6; ++face)
1268     {
1269         hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1270         ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1271
1272         hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1273         ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1274
1275         IDirect3DSurface9_Release(face_surface);
1276     }
1277
1278     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1279     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1280
1281     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1282     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1283     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1284     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1285     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1286     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1287
1288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1290
1291     for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1292     {
1293         DWORD color;
1294
1295         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1296         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1297         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1298         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1299
1300         hr = IDirect3DDevice9_BeginScene(device);
1301         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1302
1303         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1304         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1305
1306         hr = IDirect3DDevice9_EndScene(device);
1307         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1308
1309         color = getPixelColor(device, 320, 240);
1310         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
1311                 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
1312                 color, address_modes[x].name);
1313
1314         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1316
1317         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1318         ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1319     }
1320
1321     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1322     ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1323
1324     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1325     IDirect3DCubeTexture9_Release(texture);
1326     IDirect3DSurface9_Release(surface);
1327 }
1328
1329 static void offscreen_test(IDirect3DDevice9 *device)
1330 {
1331     HRESULT hr;
1332     IDirect3DTexture9 *offscreenTexture = NULL;
1333     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1334     DWORD color;
1335
1336     static const float quad[][5] = {
1337         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1338         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
1339         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1340         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
1341     };
1342
1343     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1344     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1345
1346     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1347     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1348     if(!offscreenTexture) {
1349         trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1350         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1351         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1352         if(!offscreenTexture) {
1353             skip("Cannot create an offscreen render target\n");
1354             goto out;
1355         }
1356     }
1357
1358     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1359     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1360     if(!backbuffer) {
1361         goto out;
1362     }
1363
1364     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1365     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1366     if(!offscreen) {
1367         goto out;
1368     }
1369
1370     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1371     ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1372
1373     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1374     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1375     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1376     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1377     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1378     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1379     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1380     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1381     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1382     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1383
1384     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1385         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1386         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1387         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1388         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1389
1390         /* Draw without textures - Should result in a white quad */
1391         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1392         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1393
1394         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1395         ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1396         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1397         ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1398
1399         /* This time with the texture */
1400         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1401         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1402
1403         IDirect3DDevice9_EndScene(device);
1404     }
1405
1406     /* Center quad - should be white */
1407     color = getPixelColor(device, 320, 240);
1408     ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1409     /* Some quad in the cleared part of the texture */
1410     color = getPixelColor(device, 170, 240);
1411     ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1412     /* Part of the originally cleared back buffer */
1413     color = getPixelColor(device, 10, 10);
1414     ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1415     if(0) {
1416         /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1417          * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1418          * the offscreen rendering mode this test would succeed or fail
1419          */
1420         color = getPixelColor(device, 10, 470);
1421         ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1422     }
1423
1424     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1425
1426 out:
1427     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1428     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture returned %#x.\n", hr);
1429
1430     /* restore things */
1431     if(backbuffer) {
1432         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1433         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget returned %#x.\n", hr);
1434         IDirect3DSurface9_Release(backbuffer);
1435     }
1436     if(offscreenTexture) {
1437         IDirect3DTexture9_Release(offscreenTexture);
1438     }
1439     if(offscreen) {
1440         IDirect3DSurface9_Release(offscreen);
1441     }
1442 }
1443
1444 /* This test tests fog in combination with shaders.
1445  * What's tested: linear fog (vertex and table) with pixel shader
1446  *                linear table fog with non foggy vertex shader
1447  *                vertex fog with foggy vertex shader, non-linear
1448  *                fog with shader, non-linear fog with foggy shader,
1449  *                linear table fog with foggy shader
1450  */
1451 static void fog_with_shader_test(IDirect3DDevice9 *device)
1452 {
1453     HRESULT hr;
1454     DWORD color;
1455     union {
1456         float f;
1457         DWORD i;
1458     } start, end;
1459     unsigned int i, j;
1460
1461     /* basic vertex shader without fog computation ("non foggy") */
1462     static const DWORD vertex_shader_code1[] = {
1463         0xfffe0101,                                                             /* vs_1_1                       */
1464         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
1465         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                */
1466         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
1467         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                  */
1468         0x0000ffff
1469     };
1470     /* basic vertex shader with reversed fog computation ("foggy") */
1471     static const DWORD vertex_shader_code2[] = {
1472         0xfffe0101,                                                             /* vs_1_1                        */
1473         0x0000001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0               */
1474         0x0000001f, 0x8000000a, 0x900f0001,                                     /* dcl_color0 v1                 */
1475         0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1476         0x00000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                  */
1477         0x00000001, 0xd00f0000, 0x90e40001,                                     /* mov oD0, v1                   */
1478         0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000,                         /* add r0, v0.z, c0.z            */
1479         0x00000005, 0xc00f0001, 0x80000000, 0xa0000000,                         /* mul oFog, r0.x, c0.x          */
1480         0x0000ffff
1481     };
1482     /* basic pixel shader */
1483     static const DWORD pixel_shader_code[] = {
1484         0xffff0101,                                                             /* ps_1_1     */
1485         0x00000001, 0x800f0000, 0x90e40000,                                     /* mov r0, vo */
1486         0x0000ffff
1487     };
1488
1489     static struct vertex quad[] = {
1490         {-1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1491         {-1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1492         { 1.0f, -1.0f,  0.0f,          0xFFFF0000  },
1493         { 1.0f,  1.0f,  0.0f,          0xFFFF0000  },
1494     };
1495
1496     static const D3DVERTEXELEMENT9 decl_elements[] = {
1497         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1498         {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,    D3DDECLUSAGE_COLOR, 0},
1499         D3DDECL_END()
1500     };
1501
1502     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1503     IDirect3DVertexShader9      *vertex_shader[3]   = {NULL, NULL, NULL};
1504     IDirect3DPixelShader9       *pixel_shader[2]    = {NULL, NULL};
1505
1506     /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1507     static const struct test_data_t {
1508         int vshader;
1509         int pshader;
1510         D3DFOGMODE vfog;
1511         D3DFOGMODE tfog;
1512         unsigned int color[11];
1513     } test_data[] = {
1514         /* only pixel shader: */
1515         {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1516         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1517         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1518         {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1519         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1520         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1521         {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1522         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1523         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1524         {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1525         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1526         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1527         {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1528         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1529         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1530
1531         /* vertex shader */
1532         {1, 0, D3DFOG_NONE, D3DFOG_NONE,
1533         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1534          0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1535         {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
1536         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1537         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1538         {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
1539         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1540         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1541
1542         {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
1543         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1544         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1545         {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
1546         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1547         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1548
1549         /* vertex shader and pixel shader */
1550         /* The next 4 tests would read the fog coord output, but it isn't available.
1551          * The result is a fully fogged quad, no matter what the Z coord is. This is on
1552          * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
1553          * These tests should be disabled if some other hardware behaves differently
1554          */
1555         {1, 1, D3DFOG_NONE, D3DFOG_NONE,
1556         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1557         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1558         {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1559         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1560         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1561         {1, 1, D3DFOG_EXP, D3DFOG_NONE,
1562         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1563         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1564         {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
1565         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1566         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1567
1568         /* These use the Z coordinate with linear table fog */
1569         {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1570         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1571         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1572         {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
1573         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1574         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1575         {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
1576         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1577         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1578         {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
1579         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1580         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1581
1582         /* Non-linear table fog without fog coord */
1583         {1, 1, D3DFOG_NONE, D3DFOG_EXP,
1584         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1585         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1586         {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
1587         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1588         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1589
1590 #if 0  /* FIXME: these fail on GeForce 8500 */
1591         /* foggy vertex shader */
1592         {2, 0, D3DFOG_NONE, D3DFOG_NONE,
1593         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1594          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1595         {2, 0, D3DFOG_EXP, D3DFOG_NONE,
1596         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1597          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1598         {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
1599         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1600          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1601         {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
1602         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1603          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1604 #endif
1605
1606         /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1607          * all using the fixed fog-coord linear fog
1608          */
1609         {2, 1, D3DFOG_NONE, D3DFOG_NONE,
1610         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1611          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1612         {2, 1, D3DFOG_EXP, D3DFOG_NONE,
1613         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1614          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1615         {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
1616         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1617          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1618         {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
1619         {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1620          0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1621
1622         /* These use table fog. Here the shader-provided fog coordinate is
1623          * ignored and the z coordinate used instead
1624          */
1625         {2, 1, D3DFOG_NONE, D3DFOG_EXP,
1626         {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1627         0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1628         {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
1629         {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1630         0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1631         {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
1632         {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1633         0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1634     };
1635
1636     /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1637     start.f=0.1f;
1638     end.f=0.9f;
1639
1640     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1641     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1642     hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1643     ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1644     hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1645     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1646     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1647     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1648
1649     /* Setup initial states: No lighting, fog on, fog color */
1650     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1651     ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1652     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1653     ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1654     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1655     ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1656     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1657     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1658
1659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1660     ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1662     ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1663
1664     /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1665     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1666     ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1668     ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1669
1670     for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1671     {
1672         hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1673         ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1674         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1675         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1676         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1677         ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1678         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1679         ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1680
1681         for(j=0; j < 11; j++)
1682         {
1683             /* Don't use the whole zrange to prevent rounding errors */
1684             quad[0].z = 0.001f + (float)j / 10.02f;
1685             quad[1].z = 0.001f + (float)j / 10.02f;
1686             quad[2].z = 0.001f + (float)j / 10.02f;
1687             quad[3].z = 0.001f + (float)j / 10.02f;
1688
1689             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1690             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1691
1692             hr = IDirect3DDevice9_BeginScene(device);
1693             ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1694
1695             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1696             ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1697
1698             hr = IDirect3DDevice9_EndScene(device);
1699             ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1700
1701             /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1702             color = getPixelColor(device, 128, 240);
1703             ok(color_match(color, test_data[i].color[j], 13),
1704                 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1705                 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1706
1707             IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1708         }
1709     }
1710
1711     /* reset states */
1712     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1713     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1714     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1715     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1716     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1717     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1718     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1719     ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1720
1721     IDirect3DVertexShader9_Release(vertex_shader[1]);
1722     IDirect3DVertexShader9_Release(vertex_shader[2]);
1723     IDirect3DPixelShader9_Release(pixel_shader[1]);
1724     IDirect3DVertexDeclaration9_Release(vertex_declaration);
1725 }
1726
1727 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1728     unsigned int i, x, y;
1729     HRESULT hr;
1730     IDirect3DTexture9 *texture[2] = {NULL, NULL};
1731     D3DLOCKED_RECT locked_rect;
1732
1733     /* Generate the textures */
1734     for(i=0; i<2; i++)
1735     {
1736         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1737                                             D3DPOOL_MANAGED, &texture[i], NULL);
1738         ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1739
1740         hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1741         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1742         for (y = 0; y < 128; ++y)
1743         {
1744             if(i)
1745             { /* Set up black texture with 2x2 texel white spot in the middle */
1746                 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1747                 for (x = 0; x < 128; ++x)
1748                 {
1749                     if(y>62 && y<66 && x>62 && x<66)
1750                         *ptr++ = 0xffffffff;
1751                     else
1752                         *ptr++ = 0xff000000;
1753                 }
1754             }
1755             else
1756             { /* Set up a displacement map which points away from the center parallel to the closest axis.
1757                * (if multiplied with bumpenvmat)
1758               */
1759                 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1760                 for (x = 0; x < 128; ++x)
1761                 {
1762                     if(abs(x-64)>abs(y-64))
1763                     {
1764                         if(x < 64)
1765                             *ptr++ = 0xc000;
1766                         else
1767                             *ptr++ = 0x4000;
1768                     }
1769                     else
1770                     {
1771                         if(y < 64)
1772                             *ptr++ = 0x0040;
1773                         else
1774                             *ptr++ = 0x00c0;
1775                     }
1776                 }
1777             }
1778         }
1779         hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1780         ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1781
1782         hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1783         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1784
1785         /* Disable texture filtering */
1786         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1787         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1788         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1789         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1790
1791         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1792         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1793         hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1794         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1795     }
1796 }
1797
1798 /* test the behavior of the texbem instruction
1799  * with normal 2D and projective 2D textures
1800  */
1801 static void texbem_test(IDirect3DDevice9 *device)
1802 {
1803     HRESULT hr;
1804     DWORD color;
1805     int i;
1806
1807     static const DWORD pixel_shader_code[] = {
1808         0xffff0101,                         /* ps_1_1*/
1809         0x00000042, 0xb00f0000,             /* tex t0*/
1810         0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1811         0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1812         0x0000ffff
1813     };
1814     static const DWORD double_texbem_code[] =  {
1815         0xffff0103,                                         /* ps_1_3           */
1816         0x00000042, 0xb00f0000,                             /* tex t0           */
1817         0x00000043, 0xb00f0001, 0xb0e40000,                 /* texbem t1, t0    */
1818         0x00000042, 0xb00f0002,                             /* tex t2           */
1819         0x00000043, 0xb00f0003, 0xb0e40002,                 /* texbem t3, t2    */
1820         0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003,     /* add r0, t1, t3   */
1821         0x0000ffff                                          /* end              */
1822     };
1823
1824
1825     static const float quad[][7] = {
1826         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1827         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1828         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1829         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1830     };
1831     static const float quad_proj[][9] = {
1832         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f,   0.0f,   0.0f, 0.0f, 128.0f},
1833         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f,   0.0f, 128.0f, 0.0f, 128.0f},
1834         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f,   0.0f, 0.0f, 128.0f},
1835         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1836     };
1837
1838     static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1839         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1840         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1841         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1842         D3DDECL_END()
1843     },{
1844         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1845         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1846         {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1847         D3DDECL_END()
1848     } };
1849
1850     /* use asymmetric matrix to test loading */
1851     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1852
1853     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1854     IDirect3DPixelShader9       *pixel_shader       = NULL;
1855     IDirect3DTexture9           *texture            = NULL, *texture1, *texture2;
1856     D3DLOCKED_RECT locked_rect;
1857
1858     generate_bumpmap_textures(device);
1859
1860     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1861     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1862     IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1863     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1864     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1865
1866     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1867     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1868
1869     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1870     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1871
1872     for(i=0; i<2; i++)
1873     {
1874         if(i)
1875         {
1876             hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1877             ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1878         }
1879
1880         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1881         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1882         hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1883         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1884
1885         hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1886         ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1887         hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1888         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1889
1890         hr = IDirect3DDevice9_BeginScene(device);
1891         ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1892
1893         if(!i)
1894             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1895         else
1896             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1897         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1898
1899         hr = IDirect3DDevice9_EndScene(device);
1900         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1901
1902         color = getPixelColor(device, 320-32, 240);
1903         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1904         color = getPixelColor(device, 320+32, 240);
1905         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1906         color = getPixelColor(device, 320, 240-32);
1907         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1908         color = getPixelColor(device, 320, 240+32);
1909         ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1910
1911         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1912         ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1913
1914         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1915         ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1916         IDirect3DPixelShader9_Release(pixel_shader);
1917
1918         hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1919         ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1920         IDirect3DVertexDeclaration9_Release(vertex_declaration);
1921     }
1922
1923     /* clean up */
1924     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1925     ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1926
1927     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1928     ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1929
1930     for(i=0; i<2; i++)
1931     {
1932         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1933         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1934         IDirect3DTexture9_Release(texture); /* For the GetTexture */
1935         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1936         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1937         IDirect3DTexture9_Release(texture);
1938     }
1939
1940     /* Test double texbem */
1941     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1942     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1943     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1944     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1945     hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1946     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1947     hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1948     ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1949
1950     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1951     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1952     ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1953     ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1954
1955     hr = IDirect3DTexture9_UnlockRect(texture, 0);
1956     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1957
1958     hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1959     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1960     ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1961     ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1962     hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1963     ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1964
1965     {
1966         /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1967 #define tex  0x00ff0000
1968 #define tex1 0x0000ff00
1969 #define origin 0x000000ff
1970         static const DWORD pixel_data[] = {
1971             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1972             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1973             0x000000ff, tex1      , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1974             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1975             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin,     0x000000ff, tex       , 0x000000ff,
1976             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1977             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1978             0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1979         };
1980 #undef tex1
1981 #undef tex2
1982 #undef origin
1983
1984         hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1985         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1986         for(i = 0; i < 8; i++) {
1987             memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1988         }
1989         hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1990         ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1991     }
1992
1993     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1994     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1995     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1996     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1997     hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1998     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1999     hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
2000     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2001     hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2002     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2003     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
2004     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2005
2006     bumpenvmat[0] =-1.0;  bumpenvmat[2] =  2.0;
2007     bumpenvmat[1] = 0.0;  bumpenvmat[3] =  0.0;
2008     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2009     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2010     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2011     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2012     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2013     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2014     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2015     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2016
2017     bumpenvmat[0] = 1.5; bumpenvmat[2] =  0.0;
2018     bumpenvmat[1] = 0.0; bumpenvmat[3] =  0.5;
2019     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2020     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2021     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2022     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2023     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2024     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2025     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2026     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
2027
2028     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2029     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2030     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2031     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2032     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2033     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2034     hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2035     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2036     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2037     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2038     hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2039     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2040     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2041     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2042     hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2043     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
2044
2045     hr = IDirect3DDevice9_BeginScene(device);
2046     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2047     if(SUCCEEDED(hr)) {
2048         static const float double_quad[] = {
2049             -1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2050              1.0,   -1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2051             -1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2052              1.0,    1.0,   0.0,    0.0,    0.0,    0.5,    0.5,    0.0,    0.0,    0.5,    0.5,
2053         };
2054
2055         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
2056         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2057         hr = IDirect3DDevice9_EndScene(device);
2058         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2059     }
2060     color = getPixelColor(device, 320, 240);
2061     ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2062
2063     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2064     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2065     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
2066     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2067     hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
2068     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2069     hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
2070     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
2071     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2072     ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
2073
2074     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2075     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2076
2077     IDirect3DPixelShader9_Release(pixel_shader);
2078     IDirect3DTexture9_Release(texture);
2079     IDirect3DTexture9_Release(texture1);
2080     IDirect3DTexture9_Release(texture2);
2081 }
2082
2083 static void z_range_test(IDirect3DDevice9 *device)
2084 {
2085     const struct vertex quad[] =
2086     {
2087         {-1.0f,  0.0f,   1.1f,                          0xffff0000},
2088         {-1.0f,  1.0f,   1.1f,                          0xffff0000},
2089         { 1.0f,  0.0f,  -1.1f,                          0xffff0000},
2090         { 1.0f,  1.0f,  -1.1f,                          0xffff0000},
2091     };
2092     const struct vertex quad2[] =
2093     {
2094         {-1.0f,  0.0f,   1.1f,                          0xff0000ff},
2095         {-1.0f,  1.0f,   1.1f,                          0xff0000ff},
2096         { 1.0f,  0.0f,  -1.1f,                          0xff0000ff},
2097         { 1.0f,  1.0f,  -1.1f,                          0xff0000ff},
2098     };
2099
2100     const struct tvertex quad3[] =
2101     {
2102         {    0,   240,   1.1f,  1.0,                    0xffffff00},
2103         {    0,   480,   1.1f,  1.0,                    0xffffff00},
2104         {  640,   240,  -1.1f,  1.0,                    0xffffff00},
2105         {  640,   480,  -1.1f,  1.0,                    0xffffff00},
2106     };
2107     const struct tvertex quad4[] =
2108     {
2109         {    0,   240,   1.1f,  1.0,                    0xff00ff00},
2110         {    0,   480,   1.1f,  1.0,                    0xff00ff00},
2111         {  640,   240,  -1.1f,  1.0,                    0xff00ff00},
2112         {  640,   480,  -1.1f,  1.0,                    0xff00ff00},
2113     };
2114     HRESULT hr;
2115     DWORD color;
2116     IDirect3DVertexShader9 *shader;
2117     IDirect3DVertexDeclaration9 *decl;
2118     D3DCAPS9 caps;
2119     const DWORD shader_code[] = {
2120         0xfffe0101,                                     /* vs_1_1           */
2121         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0  */
2122         0x00000001, 0xc00f0000, 0x90e40000,             /* mov oPos, v0     */
2123         0x00000001, 0xd00f0000, 0xa0e40000,             /* mov oD0, c0      */
2124         0x0000ffff                                      /* end              */
2125     };
2126     static const D3DVERTEXELEMENT9 decl_elements[] = {
2127         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2128         D3DDECL_END()
2129     };
2130     /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2131      * then call Present. Then clear the color buffer to make sure it has some defined content
2132      * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2133      * by the depth value.
2134      */
2135     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
2136     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2137     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2138     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
2139     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2140     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
2141
2142     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2147     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2149     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2150     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2151     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2152
2153     hr = IDirect3DDevice9_BeginScene(device);
2154     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2155     if(hr == D3D_OK)
2156     {
2157         /* Test the untransformed vertex path */
2158         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2159         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2160         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2161         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2162         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2163         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2164
2165         /* Test the transformed vertex path */
2166         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2167         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
2168
2169         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
2170         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2171         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2172         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2173         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
2174         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2175
2176         hr = IDirect3DDevice9_EndScene(device);
2177         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2178     }
2179
2180     /* Do not test the exact corner pixels, but go pretty close to them */
2181
2182     /* Clipped because z > 1.0 */
2183     color = getPixelColor(device, 28, 238);
2184     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2185     color = getPixelColor(device, 28, 241);
2186     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2187
2188     /* Not clipped, > z buffer clear value(0.75) */
2189     color = getPixelColor(device, 31, 238);
2190     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2191     color = getPixelColor(device, 31, 241);
2192     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2193     color = getPixelColor(device, 100, 238);
2194     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2195     color = getPixelColor(device, 100, 241);
2196     ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2197
2198     /* Not clipped, < z buffer clear value */
2199     color = getPixelColor(device, 104, 238);
2200     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2201     color = getPixelColor(device, 104, 241);
2202     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2203     color = getPixelColor(device, 318, 238);
2204     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2205     color = getPixelColor(device, 318, 241);
2206     ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2207
2208     /* Clipped because z < 0.0 */
2209     color = getPixelColor(device, 321, 238);
2210     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2211     color = getPixelColor(device, 321, 241);
2212     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2213
2214     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2215     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2216
2217     /* Test the shader path */
2218     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2219     if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2220         skip("Vertex shaders not supported\n");
2221         goto out;
2222     }
2223     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2224     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2225     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2226     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2227
2228     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2229
2230     IDirect3DDevice9_SetVertexDeclaration(device, decl);
2231     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2232     IDirect3DDevice9_SetVertexShader(device, shader);
2233     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2234
2235     hr = IDirect3DDevice9_BeginScene(device);
2236     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2237     if(hr == D3D_OK)
2238     {
2239         float colorf[] = {1.0, 0.0, 0.0, 1.0};
2240         float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2241         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2242         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2243         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2244         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2245         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2246         IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2247         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2248         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2249
2250         hr = IDirect3DDevice9_EndScene(device);
2251         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2252     }
2253
2254     IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2255     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2256     IDirect3DDevice9_SetVertexShader(device, NULL);
2257     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2258
2259     IDirect3DVertexDeclaration9_Release(decl);
2260     IDirect3DVertexShader9_Release(shader);
2261
2262     /* Z < 1.0 */
2263     color = getPixelColor(device, 28, 238);
2264     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2265
2266     /* 1.0 < z < 0.75 */
2267     color = getPixelColor(device, 31, 238);
2268     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2269     color = getPixelColor(device, 100, 238);
2270     ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2271
2272     /* 0.75 < z < 0.0 */
2273     color = getPixelColor(device, 104, 238);
2274     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2275     color = getPixelColor(device, 318, 238);
2276     ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2277
2278     /* 0.0 < z */
2279     color = getPixelColor(device, 321, 238);
2280     ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2281
2282     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2283     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2284
2285     out:
2286     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2287     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2288     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2289     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2290     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2291     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2292 }
2293
2294 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2295 {
2296     D3DSURFACE_DESC desc;
2297     D3DLOCKED_RECT l;
2298     HRESULT hr;
2299     unsigned int x, y;
2300     DWORD *mem;
2301
2302     memset(&desc, 0, sizeof(desc));
2303     memset(&l, 0, sizeof(l));
2304     hr = IDirect3DSurface9_GetDesc(surface, &desc);
2305     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2306     hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2307     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2308     if(FAILED(hr)) return;
2309
2310     for(y = 0; y < desc.Height; y++)
2311     {
2312         mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2313         for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2314         {
2315             mem[x] = color;
2316         }
2317     }
2318     hr = IDirect3DSurface9_UnlockRect(surface);
2319     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2320 }
2321
2322 /* This tests a variety of possible StretchRect() situations */
2323 static void stretchrect_test(IDirect3DDevice9 *device)
2324 {
2325     HRESULT hr;
2326     IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL, *tex_rt_dest640_480 = NULL;
2327     IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL, *surf_tex_rt_dest640_480 = NULL;
2328     IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2329     IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2330     IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2331     IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2332     IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2333     IDirect3DSurface9 *orig_rt = NULL;
2334     IDirect3DSurface9 *backbuffer = NULL;
2335     DWORD color;
2336
2337     RECT src_rect64 = {0, 0, 64, 64};
2338     RECT src_rect64_flipy = {0, 64, 64, 0};
2339     RECT dst_rect64 = {0, 0, 64, 64};
2340     RECT dst_rect64_flipy = {0, 64, 64, 0};
2341
2342     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2343     ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2344     if(!orig_rt) {
2345         goto out;
2346     }
2347
2348     /* Create our temporary surfaces in system memory */
2349     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2350     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2351     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2352     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2353
2354     /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2355     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2356     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2357     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2358     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2359     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2360     ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2361
2362     /* Create render target surfaces */
2363     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2364     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2365     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2366     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2367     hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2368     ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2369     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2370     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2371
2372     /* Create render target textures */
2373     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2374     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2375     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2376     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2377     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2378     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2379     hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
2380     ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2381     if (tex_rt32) {
2382         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2383         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2384     }
2385     if (tex_rt64) {
2386         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2387         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2388     }
2389     if (tex_rt_dest64) {
2390         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2391         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2392     }
2393     if (tex_rt_dest64) {
2394         hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
2395         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2396     }
2397
2398     /* Create regular textures in D3DPOOL_DEFAULT */
2399     hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2400     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2401     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2402     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2403     hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2404     ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2405     if (tex32) {
2406         hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2407         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2408     }
2409     if (tex64) {
2410         hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2411         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2412     }
2413     if (tex_dest64) {
2414         hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2415         ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2416     }
2417
2418     /*********************************************************************
2419      * Tests for when the source parameter is an offscreen plain surface *
2420      *********************************************************************/
2421
2422     /* Fill the offscreen 64x64 surface with green */
2423     if (surf_offscreen64)
2424         fill_surface(surf_offscreen64, 0xff00ff00);
2425
2426     /* offscreenplain ==> offscreenplain, same size */
2427     if(surf_offscreen64 && surf_offscreen_dest64) {
2428         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2429         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2430
2431         if (hr == D3D_OK) {
2432             color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2433             ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2434         }
2435
2436         /* Blit without scaling */
2437         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64, 0);
2438         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2439
2440         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2441         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0);
2442         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2443
2444         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2445         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0);
2446         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2447     }
2448
2449     /* offscreenplain ==> rendertarget texture, same size */
2450     if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2451         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2452         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2453
2454         /* We can't lock rendertarget textures, so copy to our temp surface first */
2455         if (hr == D3D_OK) {
2456             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2457             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2458         }
2459
2460         if (hr == D3D_OK) {
2461             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2462             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2463         }
2464
2465         /* Blit without scaling */
2466         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2467         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2468
2469         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2470         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2471         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2472
2473         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2474         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2475         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2476     }
2477
2478     /* offscreenplain ==> rendertarget surface, same size */
2479     if(surf_offscreen64 && surf_rt_dest64) {
2480         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2481         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2482
2483         if (hr == D3D_OK) {
2484             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2485             ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2486         }
2487
2488         /* Blit without scaling */
2489         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2490         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2491
2492         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2493         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2494         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2495
2496         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2497         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2498         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2499     }
2500
2501     /* offscreenplain ==> texture, same size (should fail) */
2502     if(surf_offscreen64 && surf_tex_dest64) {
2503         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2504         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2505     }
2506
2507     /* Fill the smaller offscreen surface with red */
2508     fill_surface(surf_offscreen32, 0xffff0000);
2509
2510     /* offscreenplain ==> offscreenplain, scaling (should fail) */
2511     if(surf_offscreen32 && surf_offscreen64) {
2512         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2513         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2514     }
2515
2516     /* offscreenplain ==> rendertarget texture, scaling */
2517     if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2518         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2519         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2520
2521         /* We can't lock rendertarget textures, so copy to our temp surface first */
2522         if (hr == D3D_OK) {
2523             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2524             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2525         }
2526
2527         if (hr == D3D_OK) {
2528             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2529             ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2530         }
2531     }
2532
2533     /* offscreenplain ==> rendertarget surface, scaling */
2534     if(surf_offscreen32 && surf_rt_dest64) {
2535         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2536         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2537
2538         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2539         ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2540     }
2541
2542     /* offscreenplain ==> texture, scaling (should fail) */
2543     if(surf_offscreen32 && surf_tex_dest64) {
2544         hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2545         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2546     }
2547
2548     /************************************************************
2549      * Tests for when the source parameter is a regular texture *
2550      ************************************************************/
2551
2552     /* Fill the surface of the regular texture with blue */
2553     if (surf_tex64 && surf_temp64) {
2554         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2555         fill_surface(surf_temp64, 0xff0000ff);
2556         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2557         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2558     }
2559
2560     /* texture ==> offscreenplain, same size */
2561     if(surf_tex64 && surf_offscreen64) {
2562         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2563         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2564     }
2565
2566     /* texture ==> rendertarget texture, same size */
2567     if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2568         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2569         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2570
2571         /* We can't lock rendertarget textures, so copy to our temp surface first */
2572         if (hr == D3D_OK) {
2573             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2574             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2575         }
2576
2577         if (hr == D3D_OK) {
2578             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2579             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2580         }
2581
2582         /* Blit without scaling */
2583         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2584         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2585
2586         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2587         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2588         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2589
2590         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2591         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2592         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2593     }
2594
2595     /* texture ==> rendertarget surface, same size */
2596     if(surf_tex64 && surf_rt_dest64) {
2597         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2598         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2599
2600         if (hr == D3D_OK) {
2601             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2602             ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2603         }
2604
2605         /* Blit without scaling */
2606         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2607         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2608
2609         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2610         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2611         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2612
2613         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2614         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2615         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2616     }
2617
2618     /* texture ==> texture, same size (should fail) */
2619     if(surf_tex64 && surf_tex_dest64) {
2620         hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2621         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2622     }
2623
2624     /* Fill the surface of the smaller regular texture with red */
2625     if (surf_tex32 && surf_temp32) {
2626         /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2627         fill_surface(surf_temp32, 0xffff0000);
2628         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2629         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2630     }
2631
2632     /* texture ==> offscreenplain, scaling (should fail) */
2633     if(surf_tex32 && surf_offscreen64) {
2634         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2635         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2636     }
2637
2638     /* texture ==> rendertarget texture, scaling */
2639     if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2640         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2641         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2642
2643         /* We can't lock rendertarget textures, so copy to our temp surface first */
2644         if (hr == D3D_OK) {
2645             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2646             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2647         }
2648
2649         if (hr == D3D_OK) {
2650             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2651             ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2652         }
2653     }
2654
2655     /* texture ==> rendertarget surface, scaling */
2656     if(surf_tex32 && surf_rt_dest64) {
2657         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2658         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2659
2660         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2661         ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2662     }
2663
2664     /* texture ==> texture, scaling (should fail) */
2665     if(surf_tex32 && surf_tex_dest64) {
2666         hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2667         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2668     }
2669
2670     /*****************************************************************
2671      * Tests for when the source parameter is a rendertarget texture *
2672      *****************************************************************/
2673
2674     /* Fill the surface of the rendertarget texture with white */
2675     if (surf_tex_rt64 && surf_temp64) {
2676         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2677         fill_surface(surf_temp64, 0xffffffff);
2678         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2679         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2680     }
2681
2682     /* rendertarget texture ==> offscreenplain, same size */
2683     if(surf_tex_rt64 && surf_offscreen64) {
2684         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2685         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2686     }
2687
2688     /* rendertarget texture ==> rendertarget texture, same size */
2689     if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2690         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2691         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2692
2693         /* We can't lock rendertarget textures, so copy to our temp surface first */
2694         if (hr == D3D_OK) {
2695             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2696             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2697         }
2698
2699         if (hr == D3D_OK) {
2700             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2701             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2702         }
2703
2704         /* Blit without scaling */
2705         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2706         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2707
2708         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2709         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2710         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2711
2712         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2713         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2714         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2715     }
2716
2717     /* rendertarget texture ==> rendertarget surface, same size */
2718     if(surf_tex_rt64 && surf_rt_dest64) {
2719         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2720         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2721
2722         if (hr == D3D_OK) {
2723             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2724             ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2725         }
2726
2727         /* Blit without scaling */
2728         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2729         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2730
2731         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2732         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0);
2733         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2734
2735         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2736         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2737         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2738     }
2739
2740     /* rendertarget texture ==> texture, same size (should fail) */
2741     if(surf_tex_rt64 && surf_tex_dest64) {
2742         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2743         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2744     }
2745
2746     /* Fill the surface of the smaller rendertarget texture with red */
2747     if (surf_tex_rt32 && surf_temp32) {
2748         /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2749         fill_surface(surf_temp32, 0xffff0000);
2750         hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2751         ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2752     }
2753
2754     /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2755     if(surf_tex_rt32 && surf_offscreen64) {
2756         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2757         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2758     }
2759
2760     /* rendertarget texture ==> rendertarget texture, scaling */
2761     if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2762         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2763         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2764
2765         /* We can't lock rendertarget textures, so copy to our temp surface first */
2766         if (hr == D3D_OK) {
2767             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2768             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2769         }
2770
2771         if (hr == D3D_OK) {
2772             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2773             ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2774         }
2775     }
2776
2777     /* rendertarget texture ==> rendertarget surface, scaling */
2778     if(surf_tex_rt32 && surf_rt_dest64) {
2779         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2780         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2781
2782         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2783         ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2784     }
2785
2786     /* rendertarget texture ==> texture, scaling (should fail) */
2787     if(surf_tex_rt32 && surf_tex_dest64) {
2788         hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2789         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2790     }
2791
2792     /*****************************************************************
2793      * Tests for when the source parameter is a rendertarget surface *
2794      *****************************************************************/
2795
2796     /* Fill the surface of the rendertarget surface with black */
2797     if (surf_rt64)
2798         fill_surface(surf_rt64, 0xff000000);
2799
2800     /* rendertarget texture ==> offscreenplain, same size */
2801     if(surf_rt64 && surf_offscreen64) {
2802         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2803         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2804     }
2805
2806     /* rendertarget surface ==> rendertarget texture, same size */
2807     if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2808         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2809         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2810
2811         /* We can't lock rendertarget textures, so copy to our temp surface first */
2812         if (hr == D3D_OK) {
2813             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2814             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2815         }
2816
2817         if (hr == D3D_OK) {
2818             color = getPixelColorFromSurface(surf_temp64, 32, 32);
2819             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2820         }
2821
2822         /* Blit without scaling */
2823         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64, 0);
2824         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2825
2826         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2827         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0);
2828         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2829
2830         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2831         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0);
2832         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2833     }
2834
2835     /* rendertarget surface ==> rendertarget surface, same size */
2836     if(surf_rt64 && surf_rt_dest64) {
2837         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2838         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2839
2840         if (hr == D3D_OK) {
2841             color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2842             ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2843         }
2844
2845         /* Blit without scaling */
2846         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64, 0);
2847         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2848
2849         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2850         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0);
2851         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2852
2853         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2854         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0);
2855         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2856     }
2857
2858     /* rendertarget surface ==> texture, same size (should fail) */
2859     if(surf_rt64 && surf_tex_dest64) {
2860         hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2861         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2862     }
2863
2864     /* Fill the surface of the smaller rendertarget texture with red */
2865     if (surf_rt32)
2866         fill_surface(surf_rt32, 0xffff0000);
2867
2868     /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2869     if(surf_rt32 && surf_offscreen64) {
2870         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2871         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2872     }
2873
2874     /* rendertarget surface ==> rendertarget texture, scaling */
2875     if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2876         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2877         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2878
2879         /* We can't lock rendertarget textures, so copy to our temp surface first */
2880         if (hr == D3D_OK) {
2881             hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2882             ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2883         }
2884
2885         if (hr == D3D_OK) {
2886             color = getPixelColorFromSurface(surf_temp64, 48, 48);
2887             ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2888         }
2889     }
2890
2891     /* rendertarget surface ==> rendertarget surface, scaling */
2892     if(surf_rt32 && surf_rt_dest64) {
2893         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2894         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2895
2896         color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2897         ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2898     }
2899
2900     /* rendertarget surface ==> texture, scaling (should fail) */
2901     if(surf_rt32 && surf_tex_dest64) {
2902         hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2903         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2904     }
2905
2906     /* backbuffer ==> surface tests (no scaling) */
2907     if(backbuffer && surf_tex_rt_dest640_480)
2908     {
2909         RECT src_rect = {0, 0, 640, 480};
2910         RECT src_rect_flipy = {0, 480, 640, 0};
2911         RECT dst_rect = {0, 0, 640, 480};
2912         RECT dst_rect_flipy = {0, 480, 640, 0};
2913
2914         /* Blit with NULL rectangles */
2915         hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, 0);
2916         ok( hr == D3D_OK, "StretchRect backbuffer ==> texture same size failed:\n");
2917
2918         /* Blit without scaling */
2919         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect, 0);
2920         ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2921
2922         /* Flipping in y-direction through src_rect, no scaling (not allowed) */
2923         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0);
2924         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2925
2926         /* Flipping in y-direction through dst_rect, no scaling (not allowed) */
2927         hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0);
2928         todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2929     }
2930
2931     /* TODO: Test format conversions */
2932
2933
2934 out:
2935     /* Clean up */
2936     if (backbuffer)
2937         IDirect3DSurface9_Release(backbuffer);
2938     if (surf_rt32)
2939         IDirect3DSurface9_Release(surf_rt32);
2940     if (surf_rt64)
2941         IDirect3DSurface9_Release(surf_rt64);
2942     if (surf_rt_dest64)
2943         IDirect3DSurface9_Release(surf_rt_dest64);
2944     if (surf_temp32)
2945         IDirect3DSurface9_Release(surf_temp32);
2946     if (surf_temp64)
2947         IDirect3DSurface9_Release(surf_temp64);
2948     if (surf_offscreen32)
2949         IDirect3DSurface9_Release(surf_offscreen32);
2950     if (surf_offscreen64)
2951         IDirect3DSurface9_Release(surf_offscreen64);
2952     if (surf_offscreen_dest64)
2953         IDirect3DSurface9_Release(surf_offscreen_dest64);
2954
2955     if (tex_rt32) {
2956         if (surf_tex_rt32)
2957             IDirect3DSurface9_Release(surf_tex_rt32);
2958         IDirect3DTexture9_Release(tex_rt32);
2959     }
2960     if (tex_rt64) {
2961         if (surf_tex_rt64)
2962             IDirect3DSurface9_Release(surf_tex_rt64);
2963         IDirect3DTexture9_Release(tex_rt64);
2964     }
2965     if (tex_rt_dest64) {
2966         if (surf_tex_rt_dest64)
2967             IDirect3DSurface9_Release(surf_tex_rt_dest64);
2968         IDirect3DTexture9_Release(tex_rt_dest64);
2969     }
2970     if (tex_rt_dest640_480) {
2971         if (surf_tex_rt_dest640_480)
2972             IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
2973         IDirect3DTexture9_Release(tex_rt_dest640_480);
2974     }
2975     if (tex32) {
2976         if (surf_tex32)
2977             IDirect3DSurface9_Release(surf_tex32);
2978         IDirect3DTexture9_Release(tex32);
2979     }
2980     if (tex64) {
2981         if (surf_tex64)
2982             IDirect3DSurface9_Release(surf_tex64);
2983         IDirect3DTexture9_Release(tex64);
2984     }
2985     if (tex_dest64) {
2986         if (surf_tex_dest64)
2987             IDirect3DSurface9_Release(surf_tex_dest64);
2988         IDirect3DTexture9_Release(tex_dest64);
2989     }
2990
2991     if (orig_rt) {
2992         hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2993         ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2994         IDirect3DSurface9_Release(orig_rt);
2995     }
2996 }
2997
2998 static void maxmip_test(IDirect3DDevice9 *device)
2999 {
3000     IDirect3DTexture9 *texture = NULL;
3001     IDirect3DSurface9 *surface = NULL;
3002     HRESULT hr;
3003     DWORD color;
3004     static const struct
3005     {
3006         struct
3007         {
3008             float x, y, z;
3009             float s, t;
3010         }
3011         v[4];
3012     }
3013     quads[] =
3014     {
3015         {{
3016             {-1.0, -1.0,  0.0,  0.0,  0.0},
3017             {-1.0,  0.0,  0.0,  0.0,  1.0},
3018             { 0.0, -1.0,  0.0,  1.0,  0.0},
3019             { 0.0,  0.0,  0.0,  1.0,  1.0},
3020         }},
3021         {{
3022             { 0.0, -1.0,  0.0,  0.0,  0.0},
3023             { 0.0,  0.0,  0.0,  0.0,  1.0},
3024             { 1.0, -1.0,  0.0,  1.0,  0.0},
3025             { 1.0,  0.0,  0.0,  1.0,  1.0},
3026         }},
3027         {{
3028             { 0.0,  0.0,  0.0,  0.0,  0.0},
3029             { 0.0,  1.0,  0.0,  0.0,  1.0},
3030             { 1.0,  0.0,  0.0,  1.0,  0.0},
3031             { 1.0,  1.0,  0.0,  1.0,  1.0},
3032         }},
3033         {{
3034             {-1.0,  0.0,  0.0,  0.0,  0.0},
3035             {-1.0,  1.0,  0.0,  0.0,  1.0},
3036             { 0.0,  0.0,  0.0,  1.0,  0.0},
3037             { 0.0,  1.0,  0.0,  1.0,  1.0},
3038         }},
3039     };
3040
3041     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3042                                         &texture, NULL);
3043     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3044     if(!texture)
3045     {
3046         skip("Failed to create test texture\n");
3047         return;
3048     }
3049
3050     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3051     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3052     fill_surface(surface, 0xffff0000);
3053     IDirect3DSurface9_Release(surface);
3054     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
3055     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3056     fill_surface(surface, 0xff00ff00);
3057     IDirect3DSurface9_Release(surface);
3058     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
3059     ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
3060     fill_surface(surface, 0xff0000ff);
3061     IDirect3DSurface9_Release(surface);
3062
3063     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3064     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3065     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3066     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3067
3068     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3069     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3070
3071     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3072     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3073
3074     hr = IDirect3DDevice9_BeginScene(device);
3075     if(SUCCEEDED(hr))
3076     {
3077         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3078         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3080         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3081
3082         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3083         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3084         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3085         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3086
3087         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3088         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3089         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3090         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3091
3092         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3093         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3094         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3095         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3096         hr = IDirect3DDevice9_EndScene(device);
3097         ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
3098     }
3099
3100     /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
3101     color = getPixelColor(device, 160, 360);
3102     ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
3103     color = getPixelColor(device, 480, 360);
3104     ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
3105     color = getPixelColor(device, 480, 120);
3106     ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
3107     color = getPixelColor(device, 160, 120);
3108     ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
3109     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3110     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3111
3112     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3113     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3114
3115     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3116     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3117
3118     hr = IDirect3DDevice9_BeginScene(device);
3119     if(SUCCEEDED(hr))
3120     {
3121         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3122         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3123         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3124         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3125
3126         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3127         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3128         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3129         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3130
3131         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3132         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3133         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3134         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3135
3136         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
3137         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3138         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3139         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3140         hr = IDirect3DDevice9_EndScene(device);
3141         ok(SUCCEEDED(hr), "IDirect3DDevice9_EndScene returned %#x.\n", hr);
3142     }
3143
3144     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3145      * level 3 (> levels in texture) samples from the highest level in the
3146      * texture (level 2). */
3147     color = getPixelColor(device, 160, 360);
3148     ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
3149     color = getPixelColor(device, 480, 360);
3150     ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
3151     color = getPixelColor(device, 480, 120);
3152     ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
3153     color = getPixelColor(device, 160, 120);
3154     ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
3155     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3156     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3157
3158     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
3159     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3160
3161     hr = IDirect3DDevice9_BeginScene(device);
3162     if(SUCCEEDED(hr))
3163     {
3164         DWORD ret;
3165
3166         /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
3167         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3168         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3169         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3170         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3171         ret = IDirect3DTexture9_SetLOD(texture, 1);
3172         ok(ret == 0, "IDirect3DTexture9_SetLOD returned %u, expected 0\n", ret);
3173         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
3174         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3175
3176         /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
3177         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3178         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3179         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
3180         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3181         ret = IDirect3DTexture9_SetLOD(texture, 2);
3182         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3183         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
3184         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3185
3186         /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
3187         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3188         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3189         ret = IDirect3DTexture9_SetLOD(texture, 1);
3190         ok(ret == 2, "IDirect3DTexture9_SetLOD returned %u, expected 2\n", ret);
3191         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
3192         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3193
3194         /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
3195         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3196         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3197         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
3198         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3199         ret = IDirect3DTexture9_SetLOD(texture, 1);
3200         ok(ret == 1, "IDirect3DTexture9_SetLOD returned %u, expected 1\n", ret);
3201         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
3202         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3203         hr = IDirect3DDevice9_EndScene(device);
3204         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3205     }
3206
3207     /* Max Mip level 0-2 sample from the specified texture level, Max Mip
3208      * level 3 (> levels in texture) samples from the highest level in the
3209      * texture (level 2). */
3210     color = getPixelColor(device, 160, 360);
3211     ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
3212     color = getPixelColor(device, 480, 360);
3213     ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
3214     color = getPixelColor(device, 480, 120);
3215     ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
3216     color = getPixelColor(device, 160, 120);
3217     ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
3218
3219     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3220     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3221
3222     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3223     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3224     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3225     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3226     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
3227     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
3228     IDirect3DTexture9_Release(texture);
3229 }
3230
3231 static void release_buffer_test(IDirect3DDevice9 *device)
3232 {
3233     IDirect3DVertexBuffer9 *vb = NULL;
3234     IDirect3DIndexBuffer9 *ib = NULL;
3235     HRESULT hr;
3236     BYTE *data;
3237     LONG ref;
3238
3239     static const struct vertex quad[] = {
3240         {-1.0,      -1.0,       0.1,        0xffff0000},
3241         {-1.0,       1.0,       0.1,        0xffff0000},
3242         { 1.0,       1.0,       0.1,        0xffff0000},
3243
3244         {-1.0,      -1.0,       0.1,        0xff00ff00},
3245         {-1.0,       1.0,       0.1,        0xff00ff00},
3246         { 1.0,       1.0,       0.1,        0xff00ff00}
3247     };
3248     short indices[] = {3, 4, 5};
3249
3250     /* Index and vertex buffers should always be creatable */
3251     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
3252                                               D3DPOOL_MANAGED, &vb, NULL);
3253     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
3254     if(!vb) {
3255         skip("Failed to create a vertex buffer\n");
3256         return;
3257     }
3258     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
3259     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
3260     if(!ib) {
3261         skip("Failed to create an index buffer\n");
3262         return;
3263     }
3264
3265     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
3266     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
3267     memcpy(data, quad, sizeof(quad));
3268     hr = IDirect3DVertexBuffer9_Unlock(vb);
3269     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
3270
3271     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
3272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
3273     memcpy(data, indices, sizeof(indices));
3274     hr = IDirect3DIndexBuffer9_Unlock(ib);
3275     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3276
3277     hr = IDirect3DDevice9_SetIndices(device, ib);
3278     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
3279     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
3280     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
3281     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3282     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3283
3284     /* Now destroy the bound index buffer and draw again */
3285     ref = IDirect3DIndexBuffer9_Release(ib);
3286     ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
3287
3288     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3289     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
3290
3291     hr = IDirect3DDevice9_BeginScene(device);
3292     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3293     if(SUCCEEDED(hr))
3294     {
3295         /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
3296          * making assumptions about the indices or vertices
3297          */
3298         hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
3299         ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
3300         hr = IDirect3DDevice9_EndScene(device);
3301         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3302     }
3303
3304     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3305     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3306
3307     hr = IDirect3DDevice9_SetIndices(device, NULL);
3308     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3309     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
3310     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
3311
3312     /* Index buffer was already destroyed as part of the test */
3313     IDirect3DVertexBuffer9_Release(vb);
3314 }
3315
3316 static void float_texture_test(IDirect3DDevice9 *device)
3317 {
3318     IDirect3D9 *d3d = NULL;
3319     HRESULT hr;
3320     IDirect3DTexture9 *texture = NULL;
3321     D3DLOCKED_RECT lr;
3322     float *data;
3323     DWORD color;
3324     float quad[] = {
3325         -1.0,      -1.0,       0.1,     0.0,    0.0,
3326         -1.0,       1.0,       0.1,     0.0,    1.0,
3327          1.0,      -1.0,       0.1,     1.0,    0.0,
3328          1.0,       1.0,       0.1,     1.0,    1.0,
3329     };
3330
3331     memset(&lr, 0, sizeof(lr));
3332     IDirect3DDevice9_GetDirect3D(device, &d3d);
3333     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3334                                      D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
3335         skip("D3DFMT_R32F textures not supported\n");
3336         goto out;
3337     }
3338
3339     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
3340                                         D3DPOOL_MANAGED, &texture, NULL);
3341     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3342     if(!texture) {
3343         skip("Failed to create R32F texture\n");
3344         goto out;
3345     }
3346
3347     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3348     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3349     data = lr.pBits;
3350     *data = 0.0;
3351     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3352     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3353
3354     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3355     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3356
3357     hr = IDirect3DDevice9_BeginScene(device);
3358     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3359     if(SUCCEEDED(hr))
3360     {
3361         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3362         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3363
3364         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3365         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3366
3367         hr = IDirect3DDevice9_EndScene(device);
3368         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3369     }
3370     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3371     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3372
3373     color = getPixelColor(device, 240, 320);
3374     ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
3375
3376     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3377     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3378
3379 out:
3380     if(texture) IDirect3DTexture9_Release(texture);
3381     IDirect3D9_Release(d3d);
3382 }
3383
3384 static void g16r16_texture_test(IDirect3DDevice9 *device)
3385 {
3386     IDirect3D9 *d3d = NULL;
3387     HRESULT hr;
3388     IDirect3DTexture9 *texture = NULL;
3389     D3DLOCKED_RECT lr;
3390     DWORD *data;
3391     DWORD color;
3392     float quad[] = {
3393        -1.0,      -1.0,       0.1,     0.0,    0.0,
3394        -1.0,       1.0,       0.1,     0.0,    1.0,
3395         1.0,      -1.0,       0.1,     1.0,    0.0,
3396         1.0,       1.0,       0.1,     1.0,    1.0,
3397     };
3398
3399     memset(&lr, 0, sizeof(lr));
3400     IDirect3DDevice9_GetDirect3D(device, &d3d);
3401     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3402        D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
3403            skip("D3DFMT_G16R16 textures not supported\n");
3404            goto out;
3405     }
3406
3407     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
3408                                         D3DPOOL_MANAGED, &texture, NULL);
3409     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
3410     if(!texture) {
3411         skip("Failed to create D3DFMT_G16R16 texture\n");
3412         goto out;
3413     }
3414
3415     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3416     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3417     data = lr.pBits;
3418     *data = 0x0f00f000;
3419     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3420     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3421
3422     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3423     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3424
3425     hr = IDirect3DDevice9_BeginScene(device);
3426     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3427     if(SUCCEEDED(hr))
3428     {
3429         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3430         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3431
3432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3433         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3434
3435         hr = IDirect3DDevice9_EndScene(device);
3436         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3437     }
3438     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3439     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3440
3441     color = getPixelColor(device, 240, 320);
3442     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
3443        "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
3444
3445     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3446     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3447
3448 out:
3449     if(texture) IDirect3DTexture9_Release(texture);
3450     IDirect3D9_Release(d3d);
3451 }
3452
3453 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3454 {
3455     HRESULT hr;
3456     IDirect3D9 *d3d;
3457     D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3458     D3DCAPS9 caps;
3459     IDirect3DTexture9 *texture = NULL;
3460     IDirect3DVolumeTexture9 *volume = NULL;
3461     unsigned int x, y, z;
3462     D3DLOCKED_RECT lr;
3463     D3DLOCKED_BOX lb;
3464     DWORD color;
3465     UINT w, h;
3466     IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3467     float identity[16] = {1.0, 0.0, 0.0, 0.0,
3468                            0.0, 1.0, 0.0, 0.0,
3469                            0.0, 0.0, 1.0, 0.0,
3470                            0.0, 0.0, 0.0, 1.0};
3471     static const D3DVERTEXELEMENT9 decl_elements[] = {
3472         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3473         {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3474         D3DDECL_END()
3475     };
3476     static const D3DVERTEXELEMENT9 decl_elements2[] = {
3477         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3478         {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3479         D3DDECL_END()
3480     };
3481     static const D3DVERTEXELEMENT9 decl_elements3[] = {
3482         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3483         {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3484         D3DDECL_END()
3485     };
3486     static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3487                                                  0x00, 0xff, 0x00, 0x00,
3488                                                  0x00, 0x00, 0x00, 0x00,
3489                                                  0x00, 0x00, 0x00, 0x00};
3490
3491     memset(&lr, 0, sizeof(lr));
3492     memset(&lb, 0, sizeof(lb));
3493     IDirect3DDevice9_GetDirect3D(device, &d3d);
3494     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3495                                      D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3496         fmt = D3DFMT_A16B16G16R16;
3497     }
3498     IDirect3D9_Release(d3d);
3499
3500     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3501     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3502     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3503     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3504     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3505     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3506     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3507     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3508     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3509     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3510     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3511     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3512     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3513     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3514     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3515     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3516     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3517     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3518     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3519     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3520     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3521     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3522     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3523     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3524
3525     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3526     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3527     w = min(1024, caps.MaxTextureWidth);
3528     h = min(1024, caps.MaxTextureHeight);
3529     hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3530                                         0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3531     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3532     if(!texture) {
3533         skip("Failed to create the test texture\n");
3534         return;
3535     }
3536
3537     /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3538      * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3539      * 1.0 in red and green for the x and y coords
3540      */
3541     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3542     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3543     for(y = 0; y < h; y++) {
3544         for(x = 0; x < w; x++) {
3545             double r_f = (double) y / (double) h;
3546             double g_f = (double) x / (double) w;
3547             if(fmt == D3DFMT_A16B16G16R16) {
3548                 unsigned short r, g;
3549                 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3550                 r = (unsigned short) (r_f * 65536.0);
3551                 g = (unsigned short) (g_f * 65536.0);
3552                 dst[0] = r;
3553                 dst[1] = g;
3554                 dst[2] = 0;
3555                 dst[3] = 65535;
3556             } else {
3557                 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3558                 unsigned char r = (unsigned char) (r_f * 255.0);
3559                 unsigned char g = (unsigned char) (g_f * 255.0);
3560                 dst[0] = 0;
3561                 dst[1] = g;
3562                 dst[2] = r;
3563                 dst[3] = 255;
3564             }
3565         }
3566     }
3567     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3568     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3569     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3570     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3571
3572     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3573     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3574     hr = IDirect3DDevice9_BeginScene(device);
3575     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3576     if(SUCCEEDED(hr))
3577     {
3578         float quad1[] = {
3579             -1.0,      -1.0,       0.1,     1.0,    1.0,
3580             -1.0,       0.0,       0.1,     1.0,    1.0,
3581              0.0,      -1.0,       0.1,     1.0,    1.0,
3582              0.0,       0.0,       0.1,     1.0,    1.0,
3583         };
3584         float quad2[] = {
3585             -1.0,       0.0,       0.1,     1.0,    1.0,
3586             -1.0,       1.0,       0.1,     1.0,    1.0,
3587              0.0,       0.0,       0.1,     1.0,    1.0,
3588              0.0,       1.0,       0.1,     1.0,    1.0,
3589         };
3590         float quad3[] = {
3591              0.0,       0.0,       0.1,     0.5,    0.5,
3592              0.0,       1.0,       0.1,     0.5,    0.5,
3593              1.0,       0.0,       0.1,     0.5,    0.5,
3594              1.0,       1.0,       0.1,     0.5,    0.5,
3595         };
3596         float quad4[] = {
3597              320,       480,       0.1,     1.0,    0.0,    1.0,
3598              320,       240,       0.1,     1.0,    0.0,    1.0,
3599              640,       480,       0.1,     1.0,    0.0,    1.0,
3600              640,       240,       0.1,     1.0,    0.0,    1.0,
3601         };
3602         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3603                           0.0, 0.0, 0.0, 0.0,
3604                           0.0, 0.0, 0.0, 0.0,
3605                           0.0, 0.0, 0.0, 0.0};
3606
3607         /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3608         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3609         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3610         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3611         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3612
3613         /* What happens with transforms enabled? */
3614         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3615         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3616         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3617         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3618
3619         /* What happens if 4 coords are used, but only 2 given ?*/
3620         mat[8] = 1.0;
3621         mat[13] = 1.0;
3622         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3623         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3624         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3625         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3626         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3627         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3628
3629         /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3630          * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3631          * due to the coords in the vertices. (turns out red, indeed)
3632          */
3633         memset(mat, 0, sizeof(mat));
3634         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3635         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3636         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3637         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3638         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3639         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3640         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3641         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3642
3643         hr = IDirect3DDevice9_EndScene(device);
3644         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3645     }
3646     color = getPixelColor(device, 160, 360);
3647     ok(color_match(color, 0x00FFFF00, 1), "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3648     color = getPixelColor(device, 160, 120);
3649     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3650     color = getPixelColor(device, 480, 120);
3651     ok(color_match(color, 0x0000FF00, 1), "quad 3 has color %08x, expected 0x0000FF00\n", color);
3652     color = getPixelColor(device, 480, 360);
3653     ok(color_match(color, 0x00FF0000, 1), "quad 4 has color %08x, expected 0x00FF0000\n", color);
3654     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3655     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3656
3657     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3658     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3659
3660     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3661     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3662     hr = IDirect3DDevice9_BeginScene(device);
3663     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3664     if(SUCCEEDED(hr))
3665     {
3666         float quad1[] = {
3667             -1.0,      -1.0,       0.1,     0.8,    0.2,
3668             -1.0,       0.0,       0.1,     0.8,    0.2,
3669              0.0,      -1.0,       0.1,     0.8,    0.2,
3670              0.0,       0.0,       0.1,     0.8,    0.2,
3671         };
3672         float quad2[] = {
3673             -1.0,       0.0,       0.1,     0.5,    1.0,
3674             -1.0,       1.0,       0.1,     0.5,    1.0,
3675              0.0,       0.0,       0.1,     0.5,    1.0,
3676              0.0,       1.0,       0.1,     0.5,    1.0,
3677         };
3678         float quad3[] = {
3679              0.0,       0.0,       0.1,     0.5,    1.0,
3680              0.0,       1.0,       0.1,     0.5,    1.0,
3681              1.0,       0.0,       0.1,     0.5,    1.0,
3682              1.0,       1.0,       0.1,     0.5,    1.0,
3683         };
3684         float quad4[] = {
3685              0.0,      -1.0,       0.1,     0.8,    0.2,
3686              0.0,       0.0,       0.1,     0.8,    0.2,
3687              1.0,      -1.0,       0.1,     0.8,    0.2,
3688              1.0,       0.0,       0.1,     0.8,    0.2,
3689         };
3690         float mat[16] = {0.0, 0.0, 0.0, 0.0,
3691                           0.0, 0.0, 0.0, 0.0,
3692                           0.0, 1.0, 0.0, 0.0,
3693                           0.0, 0.0, 0.0, 0.0};
3694
3695         /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3696          */
3697         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3698         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3699         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3700         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3701
3702         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3703         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3704
3705         /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3706          * it behaves like COUNT2 because normal textures require 2 coords
3707          */
3708         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3709         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3710         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3711         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3712
3713         /* Just to be sure, the same as quad2 above */
3714         memset(mat, 0, sizeof(mat));
3715         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3716         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3717         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3718         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3719         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3720         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3721
3722         /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3723          * used? And what happens to the first?
3724          */
3725         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3726         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3727         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3728         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3729
3730         hr = IDirect3DDevice9_EndScene(device);
3731         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3732     }
3733     color = getPixelColor(device, 160, 360);
3734     ok(color_match(color, 0x00FF0000, 1), "quad 1 has color %08x, expected 0x00FF0000\n", color);
3735     color = getPixelColor(device, 160, 120);
3736     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3737     color = getPixelColor(device, 480, 120);
3738     ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
3739        "quad 3 has color %08x, expected 0x00ff8000\n", color);
3740     color = getPixelColor(device, 480, 360);
3741     ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00FF0000, 1),
3742        "quad 4 has color %08x, expected 0x0033cc00\n", color);
3743     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3744     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3745
3746     IDirect3DTexture9_Release(texture);
3747
3748     /* Test projected textures, without any fancy matrices */
3749     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3750     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3751     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3752     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3753     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3754     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3755     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3756     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3757
3758     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3759     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3760     for(x = 0; x < 4; x++) {
3761         memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3762     }
3763     hr = IDirect3DTexture9_UnlockRect(texture, 0);
3764     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3765     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3766     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3767
3768     hr = IDirect3DDevice9_BeginScene(device);
3769     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3770     if(SUCCEEDED(hr))
3771     {
3772         const float proj_quads[] = {
3773            -1.0,   -1.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3774             1.0,   -1.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3775            -1.0,    0.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3776             1.0,    0.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3777            -1.0,    0.0,    0.1,    0.0,    0.0,    4.0,    6.0,
3778             1.0,    0.0,    0.1,    4.0,    0.0,    4.0,    6.0,
3779            -1.0,    1.0,    0.1,    0.0,    4.0,    4.0,    6.0,
3780             1.0,    1.0,    0.1,    4.0,    4.0,    4.0,    6.0,
3781         };
3782
3783         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3784         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3785         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3786         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3787
3788         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3789         ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3790         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3791         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3792
3793         hr = IDirect3DDevice9_EndScene(device);
3794         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3795     }
3796
3797     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3798     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3799     IDirect3DTexture9_Release(texture);
3800
3801     color = getPixelColor(device, 158, 118);
3802     ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3803     color = getPixelColor(device, 162, 118);
3804     ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3805     color = getPixelColor(device, 158, 122);
3806     ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3807     color = getPixelColor(device, 162, 122);
3808     ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3809
3810     color = getPixelColor(device, 158, 178);
3811     ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3812     color = getPixelColor(device, 162, 178);
3813     ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3814     color = getPixelColor(device, 158, 182);
3815     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3816     color = getPixelColor(device, 162, 182);
3817     ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3818
3819     color = getPixelColor(device, 318, 118);
3820     ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3821     color = getPixelColor(device, 322, 118);
3822     ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3823     color = getPixelColor(device, 318, 122);
3824     ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3825     color = getPixelColor(device, 322, 122);
3826     ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3827
3828     color = getPixelColor(device, 318, 178);
3829     ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3830     color = getPixelColor(device, 322, 178);
3831     ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3832     color = getPixelColor(device, 318, 182);
3833     ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3834     color = getPixelColor(device, 322, 182);
3835     ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3836
3837     color = getPixelColor(device, 238, 298);
3838     ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3839     color = getPixelColor(device, 242, 298);
3840     ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3841     color = getPixelColor(device, 238, 302);
3842     ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3843     color = getPixelColor(device, 242, 302);
3844     ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3845
3846     color = getPixelColor(device, 238, 388);
3847     ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3848     color = getPixelColor(device, 242, 388);
3849     ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3850     color = getPixelColor(device, 238, 392);
3851     ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3852     color = getPixelColor(device, 242, 392);
3853     ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3854
3855     color = getPixelColor(device, 478, 298);
3856     ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3857     color = getPixelColor(device, 482, 298);
3858     ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3859     color = getPixelColor(device, 478, 302);
3860     ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3861     color = getPixelColor(device, 482, 302);
3862     ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3863
3864     color = getPixelColor(device, 478, 388);
3865     ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3866     color = getPixelColor(device, 482, 388);
3867     ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3868     color = getPixelColor(device, 478, 392);
3869     ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3870     color = getPixelColor(device, 482, 392);
3871     ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3872
3873     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3874     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3875
3876     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3877     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3878     /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3879      * Thus watch out if sampling from texels between 0 and 1.
3880      */
3881     hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3882     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3883        "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3884     if(!volume) {
3885         skip("Failed to create a volume texture\n");
3886         goto out;
3887     }
3888
3889     hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3890     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3891     for(z = 0; z < 32; z++) {
3892         for(y = 0; y < 32; y++) {
3893             for(x = 0; x < 32; x++) {
3894                 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3895                 void *mem = ((char *)  lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3896                 float r_f = (float) x / 31.0;
3897                 float g_f = (float) y / 31.0;
3898                 float b_f = (float) z / 31.0;
3899
3900                 if(fmt == D3DFMT_A16B16G16R16) {
3901                     unsigned short *mem_s = mem;
3902                     mem_s[0]  = r_f * 65535.0;
3903                     mem_s[1]  = g_f * 65535.0;
3904                     mem_s[2]  = b_f * 65535.0;
3905                     mem_s[3]  = 65535;
3906                 } else {
3907                     unsigned char *mem_c = mem;
3908                     mem_c[0]  = b_f * 255.0;
3909                     mem_c[1]  = g_f * 255.0;
3910                     mem_c[2]  = r_f * 255.0;
3911                     mem_c[3]  = 255;
3912                 }
3913             }
3914         }
3915     }
3916     hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3917     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3918
3919     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3920     ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3921
3922     hr = IDirect3DDevice9_BeginScene(device);
3923     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3924     if(SUCCEEDED(hr))
3925     {
3926         float quad1[] = {
3927             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3928             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3929              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3930              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
3931         };
3932         float quad2[] = {
3933             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3934             -1.0,       1.0,       0.1,     1.0,    1.0,    1.0,
3935              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3936              0.0,       1.0,       0.1,     1.0,    1.0,    1.0
3937         };
3938         float quad3[] = {
3939              0.0,       0.0,       0.1,     0.0,    0.0,
3940              0.0,       1.0,       0.1,     0.0,    0.0,
3941              1.0,       0.0,       0.1,     0.0,    0.0,
3942              1.0,       1.0,       0.1,     0.0,    0.0
3943         };
3944         float quad4[] = {
3945              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3946              0.0,       0.0,       0.1,     1.0,    1.0,    1.0,
3947              1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
3948              1.0,       0.0,       0.1,     1.0,    1.0,    1.0
3949         };
3950         float mat[16] = {1.0, 0.0, 0.0, 0.0,
3951                          0.0, 0.0, 1.0, 0.0,
3952                          0.0, 1.0, 0.0, 0.0,
3953                          0.0, 0.0, 0.0, 1.0};
3954         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3955         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3956
3957         /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3958          * values
3959          */
3960         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
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_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3965         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3966
3967         /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3968          * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3969          * otherwise the w will be missing(blue).
3970          * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3971          * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3972          */
3973         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3974         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3975         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3976         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3977
3978         /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
3979         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3980         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3981         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3982         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3983         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3984         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3985         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3986         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3987
3988         /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3989          * disable. ATI extends it up to the amount of values needed for the volume texture
3990          */
3991         memset(mat, 0, sizeof(mat));
3992         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3993         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3994         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3995         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3996         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3997         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3998         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3999         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4000
4001         hr = IDirect3DDevice9_EndScene(device);
4002         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4003     }
4004
4005     color = getPixelColor(device, 160, 360);
4006     ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
4007     color = getPixelColor(device, 160, 120);
4008     ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
4009        "quad 2 has color %08x, expected 0x00ffff00\n", color);
4010     color = getPixelColor(device, 480, 120);
4011     ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
4012     color = getPixelColor(device, 480, 360);
4013     ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
4014
4015     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4016     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4017
4018     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
4019     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4020     hr = IDirect3DDevice9_BeginScene(device);
4021     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4022     if(SUCCEEDED(hr))
4023     {
4024         float quad1[] = {
4025             -1.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4026             -1.0,       0.0,       0.1,     1.0,    1.0,    1.0,
4027              0.0,      -1.0,       0.1,     1.0,    1.0,    1.0,
4028              0.0,       0.0,       0.1,     1.0,    1.0,    1.0
4029         };
4030         float quad2[] = {
4031             -1.0,       0.0,       0.1,
4032             -1.0,       1.0,       0.1,
4033              0.0,       0.0,       0.1,
4034              0.0,       1.0,       0.1,
4035         };
4036         float quad3[] = {
4037              0.0,       0.0,       0.1,     1.0,
4038              0.0,       1.0,       0.1,     1.0,
4039              1.0,       0.0,       0.1,     1.0,
4040              1.0,       1.0,       0.1,     1.0
4041         };
4042         float mat[16] =  {0.0, 0.0, 0.0, 0.0,
4043                            0.0, 0.0, 0.0, 0.0,
4044                            0.0, 0.0, 0.0, 0.0,
4045                            0.0, 1.0, 0.0, 0.0};
4046         float mat2[16] = {0.0, 0.0, 0.0, 1.0,
4047                            1.0, 0.0, 0.0, 0.0,
4048                            0.0, 1.0, 0.0, 0.0,
4049                            0.0, 0.0, 1.0, 0.0};
4050         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4051         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4052
4053         /* Default values? 4 coords used, 3 passed. What happens to the 4th?
4054          * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
4055          * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
4056          * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
4057          * 4th *input* coordinate.
4058          */
4059         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
4060         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4061         IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4062         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4063         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4064         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4065
4066         /* None passed */
4067         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
4068         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4069         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4070         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4071         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4072         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4073
4074         /* 4 used, 1 passed */
4075         hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4076         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4077         hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
4078         ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4079         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
4080         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4081
4082         hr = IDirect3DDevice9_EndScene(device);
4083         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4084     }
4085     color = getPixelColor(device, 160, 360);
4086     ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
4087     color = getPixelColor(device, 160, 120);
4088     ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
4089     color = getPixelColor(device, 480, 120);
4090     ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
4091     /* Quad4: unused */
4092
4093     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4094     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4095
4096     IDirect3DVolumeTexture9_Release(volume);
4097
4098     out:
4099     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4100     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4101     IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
4102     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4103     hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
4104     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4105     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4106     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4107     IDirect3DVertexDeclaration9_Release(decl);
4108     IDirect3DVertexDeclaration9_Release(decl2);
4109     IDirect3DVertexDeclaration9_Release(decl3);
4110 }
4111
4112 static void texdepth_test(IDirect3DDevice9 *device)
4113 {
4114     IDirect3DPixelShader9 *shader;
4115     HRESULT hr;
4116     const float texdepth_test_data1[] = { 0.25,  2.0, 0.0, 0.0};
4117     const float texdepth_test_data2[] = { 0.25,  0.5, 0.0, 0.0};
4118     const float texdepth_test_data3[] = {-1.00,  0.1, 0.0, 0.0};
4119     const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
4120     const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
4121     const float texdepth_test_data6[] = { 1.00,  0.5, 0.0, 0.0};
4122     const float texdepth_test_data7[] = { 0.50,  0.0, 0.0, 0.0};
4123     DWORD shader_code[] = {
4124         0xffff0104,                                                                 /* ps_1_4               */
4125         0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,     /* def c1, 0, 0, 1, 1   */
4126         0x00000001, 0x800f0005, 0xa0e40000,                                         /* mov r5, c0           */
4127         0x0000fffd,                                                                 /* phase                */
4128         0x00000057, 0x800f0005,                                                     /* texdepth r5          */
4129         0x00000001, 0x800f0000, 0xa0e40001,                                         /* mov r0, c1           */
4130         0x0000ffff                                                                  /* end                  */
4131     };
4132     DWORD color;
4133     float vertex[] = {
4134        -1.0,   -1.0,    0.0,
4135         1.0,   -1.0,    1.0,
4136        -1.0,    1.0,    0.0,
4137         1.0,    1.0,    1.0
4138     };
4139
4140     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4141     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4142
4143     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
4144     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4145     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4146     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4147     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4148     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4149     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4150     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4151     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4152     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
4153
4154     /* Fill the depth buffer with a gradient */
4155     hr = IDirect3DDevice9_BeginScene(device);
4156     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4157     if(SUCCEEDED(hr))
4158     {
4159         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4160         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4161         hr = IDirect3DDevice9_EndScene(device);
4162         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4163     }
4164
4165     /* Now perform the actual tests. Same geometry, but with the shader */
4166     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
4167     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4168     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4169     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4170     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4171     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4172
4173     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
4174     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4175     hr = IDirect3DDevice9_BeginScene(device);
4176     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4177     if(SUCCEEDED(hr))
4178     {
4179         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4180         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4181
4182         hr = IDirect3DDevice9_EndScene(device);
4183         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4184     }
4185
4186     color = getPixelColor(device, 158, 240);
4187     ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4188     color = getPixelColor(device, 162, 240);
4189     ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
4190
4191     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4192     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4193
4194     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4195     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4196
4197     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
4198     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4199     hr = IDirect3DDevice9_BeginScene(device);
4200     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4201     if(SUCCEEDED(hr))
4202     {
4203         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4204         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4205
4206         hr = IDirect3DDevice9_EndScene(device);
4207         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4208     }
4209
4210     color = getPixelColor(device, 318, 240);
4211     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4212     color = getPixelColor(device, 322, 240);
4213     ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4214
4215     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4216     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4217
4218     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4219     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4220
4221     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
4222     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4223     hr = IDirect3DDevice9_BeginScene(device);
4224     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4225     if(SUCCEEDED(hr))
4226     {
4227         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4228         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4229
4230         hr = IDirect3DDevice9_EndScene(device);
4231         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4232     }
4233
4234     color = getPixelColor(device, 1, 240);
4235     ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
4236
4237     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4238     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4239
4240     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4241     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4242
4243     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
4244     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4245     hr = IDirect3DDevice9_BeginScene(device);
4246     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4247     if(SUCCEEDED(hr))
4248     {
4249         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4250         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4251
4252         hr = IDirect3DDevice9_EndScene(device);
4253         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4254     }
4255     color = getPixelColor(device, 318, 240);
4256     ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
4257     color = getPixelColor(device, 322, 240);
4258     ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
4259
4260     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4261     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4262
4263     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4264     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4265
4266     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
4267     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4268     hr = IDirect3DDevice9_BeginScene(device);
4269     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4270     if(SUCCEEDED(hr))
4271     {
4272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4273         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4274
4275         hr = IDirect3DDevice9_EndScene(device);
4276         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4277     }
4278
4279     color = getPixelColor(device, 1, 240);
4280     ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
4281
4282     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4283     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4284
4285     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4286     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4287
4288     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
4289     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4290     hr = IDirect3DDevice9_BeginScene(device);
4291     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4292     if(SUCCEEDED(hr))
4293     {
4294         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4295         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4296
4297         hr = IDirect3DDevice9_EndScene(device);
4298         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4299     }
4300
4301     color = getPixelColor(device, 638, 240);
4302     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4303
4304     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4305     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4306
4307     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4308     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
4309
4310     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
4311     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4312     hr = IDirect3DDevice9_BeginScene(device);
4313     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4314     if(SUCCEEDED(hr))
4315     {
4316         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
4317         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4318
4319         hr = IDirect3DDevice9_EndScene(device);
4320         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4321     }
4322
4323     color = getPixelColor(device, 638, 240);
4324     ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
4325
4326     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4327     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4328
4329     /* Cleanup */
4330     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4331     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4332     IDirect3DPixelShader9_Release(shader);
4333
4334     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4335     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4336     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4337     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
4338 }
4339
4340 static void texkill_test(IDirect3DDevice9 *device)
4341 {
4342     IDirect3DPixelShader9 *shader;
4343     HRESULT hr;
4344     DWORD color;
4345
4346     const float vertex[] = {
4347     /*                          bottom  top    right    left */
4348         -1.0,   -1.0,   1.0,   -0.1,    0.9,    0.9,   -0.1,
4349          1.0,   -1.0,   0.0,    0.9,   -0.1,    0.9,   -0.1,
4350         -1.0,    1.0,   1.0,   -0.1,    0.9,   -0.1,    0.9,
4351          1.0,    1.0,   0.0,    0.9,   -0.1,   -0.1,    0.9,
4352     };
4353
4354     DWORD shader_code_11[] = {
4355     0xffff0101,                                                             /* ps_1_1                     */
4356     0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
4357     0x00000041, 0xb00f0000,                                                 /* texkill t0                 */
4358     0x00000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
4359     0x0000ffff                                                              /* end                        */
4360     };
4361     DWORD shader_code_20[] = {
4362     0xffff0200,                                                             /* ps_2_0                     */
4363     0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                     */
4364     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
4365     0x01000041, 0xb00f0000,                                                 /* texkill t0                 */
4366     0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
4367     0x0000ffff                                                              /* end                        */
4368     };
4369
4370     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
4371     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4372     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
4373     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4374
4375     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4376     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4377     hr = IDirect3DDevice9_BeginScene(device);
4378     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4379     if(SUCCEEDED(hr))
4380     {
4381         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
4382         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4383         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4384         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4385         hr = IDirect3DDevice9_EndScene(device);
4386         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4387     }
4388     color = getPixelColor(device, 63, 46);
4389     ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
4390     color = getPixelColor(device, 66, 46);
4391     ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
4392     color = getPixelColor(device, 63, 49);
4393     ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
4394     color = getPixelColor(device, 66, 49);
4395     ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
4396
4397     color = getPixelColor(device, 578, 46);
4398     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4399     color = getPixelColor(device, 575, 46);
4400     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4401     color = getPixelColor(device, 578, 49);
4402     ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
4403     color = getPixelColor(device, 575, 49);
4404     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4405
4406     color = getPixelColor(device, 63, 430);
4407     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4408     color = getPixelColor(device, 63, 433);
4409     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4410     color = getPixelColor(device, 66, 433);
4411     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4412     color = getPixelColor(device, 66, 430);
4413     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4414
4415     color = getPixelColor(device, 578, 430);
4416     ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
4417     color = getPixelColor(device, 578, 433);
4418     ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
4419     color = getPixelColor(device, 575, 433);
4420     ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
4421     color = getPixelColor(device, 575, 430);
4422     ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
4423
4424     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4425     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4426
4427     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4428     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4429     IDirect3DPixelShader9_Release(shader);
4430
4431     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4432     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4433     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
4434     if(FAILED(hr)) {
4435         skip("Failed to create 2.0 test shader, most likely not supported\n");
4436         return;
4437     }
4438
4439     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4440     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4441     hr = IDirect3DDevice9_BeginScene(device);
4442     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4443     if(SUCCEEDED(hr))
4444     {
4445         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4446         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4447         hr = IDirect3DDevice9_EndScene(device);
4448         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4449     }
4450
4451     color = getPixelColor(device, 63, 46);
4452     ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4453     color = getPixelColor(device, 66, 46);
4454     ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4455     color = getPixelColor(device, 63, 49);
4456     ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4457     color = getPixelColor(device, 66, 49);
4458     ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4459
4460     color = getPixelColor(device, 578, 46);
4461     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4462     color = getPixelColor(device, 575, 46);
4463     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4464     color = getPixelColor(device, 578, 49);
4465     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4466     color = getPixelColor(device, 575, 49);
4467     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4468
4469     color = getPixelColor(device, 63, 430);
4470     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4471     color = getPixelColor(device, 63, 433);
4472     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4473     color = getPixelColor(device, 66, 433);
4474     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4475     color = getPixelColor(device, 66, 430);
4476     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4477
4478     color = getPixelColor(device, 578, 430);
4479     ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4480     color = getPixelColor(device, 578, 433);
4481     ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4482     color = getPixelColor(device, 575, 433);
4483     ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4484     color = getPixelColor(device, 575, 430);
4485     ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4486
4487     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4488     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4489
4490     /* Cleanup */
4491     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4492     ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4493     IDirect3DPixelShader9_Release(shader);
4494 }
4495
4496 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4497 {
4498     IDirect3D9 *d3d9;
4499     HRESULT hr;
4500     IDirect3DTexture9 *texture;
4501     IDirect3DPixelShader9 *shader;
4502     IDirect3DPixelShader9 *shader2;
4503     D3DLOCKED_RECT lr;
4504     DWORD color;
4505     DWORD shader_code[] = {
4506         0xffff0101,                             /* ps_1_1       */
4507         0x00000042, 0xb00f0000,                 /* tex t0       */
4508         0x00000001, 0x800f0000, 0xb0e40000,     /* mov r0, t0   */
4509         0x0000ffff                              /* end          */
4510     };
4511     DWORD shader_code2[] = {
4512         0xffff0101,                             /* ps_1_1       */
4513         0x00000042, 0xb00f0000,                 /* tex t0       */
4514         0x00000001, 0x800f0000, 0xb0ff0000,     /* mov r0, t0.w */
4515         0x0000ffff                              /* end          */
4516     };
4517
4518     float quad[] = {
4519        -1.0,   -1.0,   0.1,     0.5,    0.5,
4520         1.0,   -1.0,   0.1,     0.5,    0.5,
4521        -1.0,    1.0,   0.1,     0.5,    0.5,
4522         1.0,    1.0,   0.1,     0.5,    0.5,
4523     };
4524
4525     memset(&lr, 0, sizeof(lr));
4526     IDirect3DDevice9_GetDirect3D(device, &d3d9);
4527     hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4528                                       0,  D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4529     IDirect3D9_Release(d3d9);
4530     if(FAILED(hr)) {
4531         skip("No D3DFMT_X8L8V8U8 support\n");
4532         return;
4533     };
4534
4535     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4536     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4537
4538     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4539     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4540     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4541     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4542     *((DWORD *) lr.pBits) = 0x11ca3141;
4543     hr = IDirect3DTexture9_UnlockRect(texture, 0);
4544     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4545
4546     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4547     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4548     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4549     ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4550
4551     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4552     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4553     hr = IDirect3DDevice9_SetPixelShader(device, shader);
4554     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4555     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4556     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4557
4558     hr = IDirect3DDevice9_BeginScene(device);
4559     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4560     if(SUCCEEDED(hr))
4561     {
4562         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4563         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4564
4565         hr = IDirect3DDevice9_EndScene(device);
4566         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4567     }
4568     color = getPixelColor(device, 578, 430);
4569     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x82, 0x62, 0xca), 1),
4570        "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4571     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4572     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4573
4574     hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4575     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4576     hr = IDirect3DDevice9_BeginScene(device);
4577     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4578     if(SUCCEEDED(hr))
4579     {
4580         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4581         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4582
4583         hr = IDirect3DDevice9_EndScene(device);
4584         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4585     }
4586     color = getPixelColor(device, 578, 430);
4587     ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4588     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4589     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4590
4591     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4592     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4593     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4594     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4595     IDirect3DPixelShader9_Release(shader);
4596     IDirect3DPixelShader9_Release(shader2);
4597     IDirect3DTexture9_Release(texture);
4598 }
4599
4600 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4601 {
4602     HRESULT hr;
4603     IDirect3D9 *d3d;
4604     IDirect3DTexture9 *texture = NULL;
4605     IDirect3DSurface9 *surface;
4606     DWORD color;
4607     const RECT r1 = {256, 256, 512, 512};
4608     const RECT r2 = {512, 256, 768, 512};
4609     const RECT r3 = {256, 512, 512, 768};
4610     const RECT r4 = {512, 512, 768, 768};
4611     unsigned int x, y;
4612     D3DLOCKED_RECT lr;
4613     memset(&lr, 0, sizeof(lr));
4614
4615     IDirect3DDevice9_GetDirect3D(device, &d3d);
4616     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4617        D3DUSAGE_AUTOGENMIPMAP,  D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4618         skip("No autogenmipmap support\n");
4619         IDirect3D9_Release(d3d);
4620         return;
4621     }
4622     IDirect3D9_Release(d3d);
4623
4624     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4625     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4626
4627     /* Make the mipmap big, so that a smaller mipmap is used
4628      */
4629     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4630                                         D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4631     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4632
4633     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4634     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4635     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4636     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4637     for(y = 0; y < 1024; y++) {
4638         for(x = 0; x < 1024; x++) {
4639             DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4640             POINT pt;
4641
4642             pt.x = x;
4643             pt.y = y;
4644             if(PtInRect(&r1, pt)) {
4645                 *dst = 0xffff0000;
4646             } else if(PtInRect(&r2, pt)) {
4647                 *dst = 0xff00ff00;
4648             } else if(PtInRect(&r3, pt)) {
4649                 *dst = 0xff0000ff;
4650             } else if(PtInRect(&r4, pt)) {
4651                 *dst = 0xff000000;
4652             } else {
4653                 *dst = 0xffffffff;
4654             }
4655         }
4656     }
4657     hr = IDirect3DSurface9_UnlockRect(surface);
4658     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4659     IDirect3DSurface9_Release(surface);
4660
4661     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4662     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4663     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4664     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4665
4666     hr = IDirect3DDevice9_BeginScene(device);
4667     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4668     if(SUCCEEDED(hr)) {
4669         const float quad[] =  {
4670            -0.5,   -0.5,    0.1,    0.0,    0.0,
4671            -0.5,    0.5,    0.1,    0.0,    1.0,
4672             0.5,   -0.5,    0.1,    1.0,    0.0,
4673             0.5,    0.5,    0.1,    1.0,    1.0
4674         };
4675
4676         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4677         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4678         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4679         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4680         hr = IDirect3DDevice9_EndScene(device);
4681         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4682     }
4683     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4684     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4685     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4686     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4687     IDirect3DTexture9_Release(texture);
4688
4689     color = getPixelColor(device, 200, 200);
4690     ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4691     color = getPixelColor(device, 280, 200);
4692     ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4693     color = getPixelColor(device, 360, 200);
4694     ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4695     color = getPixelColor(device, 440, 200);
4696     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4697     color = getPixelColor(device, 200, 270);
4698     ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4699     color = getPixelColor(device, 280, 270);
4700     ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4701     color = getPixelColor(device, 360, 270);
4702     ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4703     color = getPixelColor(device, 440, 270);
4704     ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4705     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4706     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4707 }
4708
4709 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4710 {
4711     IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4712     IDirect3DVertexDeclaration9 *decl;
4713     HRESULT hr;
4714     DWORD color;
4715     DWORD shader_code_11[] =  {
4716         0xfffe0101,                                         /* vs_1_1           */
4717         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4718         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4719         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4720         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4721         0x0000ffff                                          /* end              */
4722     };
4723     DWORD shader_code_11_2[] =  {
4724         0xfffe0101,                                         /* vs_1_1           */
4725         0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4726         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4727         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4728         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4729         0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4730         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4731         0x0000ffff                                          /* end              */
4732     };
4733     DWORD shader_code_20[] =  {
4734         0xfffe0200,                                         /* vs_2_0           */
4735         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4736         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4737         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4738         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4739         0x0000ffff                                          /* end              */
4740     };
4741     DWORD shader_code_20_2[] =  {
4742         0xfffe0200,                                         /* vs_2_0           */
4743         0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4744         0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4745         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0  */
4746         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4747         0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002,     /* add oD0, r1, c2  */
4748         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0     */
4749         0x0000ffff                                          /* end              */
4750     };
4751     static const D3DVERTEXELEMENT9 decl_elements[] = {
4752         {0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4753         D3DDECL_END()
4754     };
4755     float quad1[] = {
4756         -1.0,   -1.0,   0.1,
4757          0.0,   -1.0,   0.1,
4758         -1.0,    0.0,   0.1,
4759          0.0,    0.0,   0.1
4760     };
4761     float quad2[] = {
4762          0.0,   -1.0,   0.1,
4763          1.0,   -1.0,   0.1,
4764          0.0,    0.0,   0.1,
4765          1.0,    0.0,   0.1
4766     };
4767     float quad3[] = {
4768          0.0,    0.0,   0.1,
4769          1.0,    0.0,   0.1,
4770          0.0,    1.0,   0.1,
4771          1.0,    1.0,   0.1
4772     };
4773     float quad4[] = {
4774         -1.0,    0.0,   0.1,
4775          0.0,    0.0,   0.1,
4776         -1.0,    1.0,   0.1,
4777          0.0,    1.0,   0.1
4778     };
4779     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4780     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4781
4782     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4783     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4784
4785     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4786     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4787     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4788     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4789     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4790     if(FAILED(hr)) shader_20 = NULL;
4791     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4792     if(FAILED(hr)) shader_20_2 = NULL;
4793     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4794     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4795
4796     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4797     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4798     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4799     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4800     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4801     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4802
4803     hr = IDirect3DDevice9_BeginScene(device);
4804     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4805     if(SUCCEEDED(hr))
4806     {
4807         hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4808         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4809         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4810         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4811
4812         hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4813         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4814         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4815         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4816
4817         if(shader_20) {
4818             hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4819             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4820             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4821             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4822         }
4823
4824         if(shader_20_2) {
4825             hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4826             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4827             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4828             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4829         }
4830
4831         hr = IDirect3DDevice9_EndScene(device);
4832         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4833     }
4834
4835     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4836     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4837     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4838     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4839
4840     color = getPixelColor(device, 160, 360);
4841     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4842        "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4843     color = getPixelColor(device, 480, 360);
4844     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4845        "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4846     if(shader_20) {
4847         color = getPixelColor(device, 480, 120);
4848         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4849            "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4850     }
4851     if(shader_20_2) {
4852         color = getPixelColor(device, 160, 120);
4853         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4854            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4855     }
4856     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4857     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4858
4859     IDirect3DVertexDeclaration9_Release(decl);
4860     if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4861     if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4862     IDirect3DVertexShader9_Release(shader_11_2);
4863     IDirect3DVertexShader9_Release(shader_11);
4864 }
4865
4866 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4867 {
4868     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4869     HRESULT hr;
4870     DWORD color;
4871     DWORD shader_code_11[] =  {
4872         0xffff0101,                                         /* ps_1_1           */
4873         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4874         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4875         0x0000ffff                                          /* end              */
4876     };
4877     DWORD shader_code_12[] =  {
4878         0xffff0102,                                         /* ps_1_2           */
4879         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4880         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4881         0x0000ffff                                          /* end              */
4882     };
4883     /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4884      * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4885      * During development of this test, 1.3 shaders were verified too
4886      */
4887     DWORD shader_code_14[] =  {
4888         0xffff0104,                                         /* ps_1_4           */
4889         /* Try to make one constant local. It gets clamped too, although the binary contains
4890          * the bigger numbers
4891          */
4892         0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4893         0x00000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4894         0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4895         0x0000ffff                                          /* end              */
4896     };
4897     DWORD shader_code_20[] =  {
4898         0xffff0200,                                         /* ps_2_0           */
4899         0x02000001, 0x800f0001, 0xa0e40001,                 /* mov r1, c1       */
4900         0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002,     /* add r0, r1, c2   */
4901         0x02000001, 0x800f0800, 0x80e40000,                 /* mov oC0, r0      */
4902         0x0000ffff                                          /* end              */
4903     };
4904     float quad1[] = {
4905         -1.0,   -1.0,   0.1,
4906          0.0,   -1.0,   0.1,
4907         -1.0,    0.0,   0.1,
4908          0.0,    0.0,   0.1
4909     };
4910     float quad2[] = {
4911          0.0,   -1.0,   0.1,
4912          1.0,   -1.0,   0.1,
4913          0.0,    0.0,   0.1,
4914          1.0,    0.0,   0.1
4915     };
4916     float quad3[] = {
4917          0.0,    0.0,   0.1,
4918          1.0,    0.0,   0.1,
4919          0.0,    1.0,   0.1,
4920          1.0,    1.0,   0.1
4921     };
4922     float quad4[] = {
4923         -1.0,    0.0,   0.1,
4924          0.0,    0.0,   0.1,
4925         -1.0,    1.0,   0.1,
4926          0.0,    1.0,   0.1
4927     };
4928     float test_data_c1[4] = {  1.25, -0.50, -1.50, 1.0};
4929     float test_data_c2[4] = { -0.50,  1.25,  2.00, 1.0};
4930
4931     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4932     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4933
4934     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4935     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4936     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4937     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4938     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4939     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4940     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4941     if(FAILED(hr)) shader_20 = NULL;
4942
4943     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4944     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4945     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4946     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4947     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4948     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4949
4950     hr = IDirect3DDevice9_BeginScene(device);
4951     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4952     if(SUCCEEDED(hr))
4953     {
4954         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4955         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4956         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4957         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4958
4959         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4960         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4961         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4962         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4963
4964         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4965         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4966         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4967         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4968
4969         if(shader_20) {
4970             hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4971             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4972             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4973             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4974         }
4975
4976         hr = IDirect3DDevice9_EndScene(device);
4977         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4978     }
4979     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4980     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4981
4982     color = getPixelColor(device, 160, 360);
4983     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4984        "quad 1 has color %08x, expected 0x00808000\n", color);
4985     color = getPixelColor(device, 480, 360);
4986     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4987        "quad 2 has color %08x, expected 0x00808000\n", color);
4988     color = getPixelColor(device, 480, 120);
4989     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
4990        "quad 3 has color %08x, expected 0x00808000\n", color);
4991     if(shader_20) {
4992         color = getPixelColor(device, 160, 120);
4993         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
4994            "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4995     }
4996     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4997     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4998
4999     if(shader_20) IDirect3DPixelShader9_Release(shader_20);
5000     IDirect3DPixelShader9_Release(shader_14);
5001     IDirect3DPixelShader9_Release(shader_12);
5002     IDirect3DPixelShader9_Release(shader_11);
5003 }
5004
5005 static void dp2add_ps_test(IDirect3DDevice9 *device)
5006 {
5007     IDirect3DPixelShader9 *shader_dp2add = NULL;
5008     IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
5009     HRESULT hr;
5010     DWORD color;
5011
5012     /* DP2ADD is defined as:  (src0.r * src1.r) + (src0.g * src1.g) + src2.
5013      * One D3D restriction of all shader instructions except SINCOS is that no more than 2
5014      * source tokens can be constants.  So, for this exercise, we move contents of c0 to
5015      * r0 first.
5016      * The result here for the r,g,b components should be roughly 0.5:
5017      *   (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
5018     static const DWORD shader_code_dp2add[] =  {
5019         0xffff0200,                                                             /* ps_2_0                       */
5020         0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0     */
5021
5022         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                   */
5023         0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add r0.rgb, r0, r0, r0.a  */
5024
5025         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b               */
5026         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
5027         0x0000ffff                                                              /* end                          */
5028     };
5029
5030     /* Test the _sat modifier, too.  Result here should be:
5031      *   DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
5032      *      _SAT: ==> 1.0
5033      *   ADD: (1.0 + -0.5) = 0.5
5034      */
5035     static const DWORD shader_code_dp2add_sat[] =  {
5036         0xffff0200,                                                             /* ps_2_0                           */
5037         0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0     */
5038
5039         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                       */
5040         0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000,             /* dp2add_sat r0.rgb, r0, r0, r0.a  */
5041         0x03000002, 0x80070000, 0x80e40000, 0xa0000000,                         /* add r0.rgb, r0, c0.r             */
5042
5043         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.a, c0.b                   */
5044         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                      */
5045         0x0000ffff                                                              /* end                              */
5046     };
5047
5048     const float quad[] = {
5049         -1.0,   -1.0,   0.1,
5050          1.0,   -1.0,   0.1,
5051         -1.0,    1.0,   0.1,
5052          1.0,    1.0,   0.1
5053     };
5054
5055
5056     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
5057     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5058
5059     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
5060     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5061
5062     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
5063     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5064
5065     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5066     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5067
5068     if (shader_dp2add) {
5069
5070         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
5071         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5072
5073         hr = IDirect3DDevice9_BeginScene(device);
5074         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5075         if(SUCCEEDED(hr))
5076         {
5077             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5078             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5079
5080             hr = IDirect3DDevice9_EndScene(device);
5081             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5082         }
5083
5084         color = getPixelColor(device, 360, 240);
5085         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5086                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5087
5088         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5089         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5090
5091         IDirect3DPixelShader9_Release(shader_dp2add);
5092     } else {
5093         skip("dp2add shader creation failed\n");
5094     }
5095
5096     if (shader_dp2add_sat) {
5097
5098         hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
5099         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5100
5101         hr = IDirect3DDevice9_BeginScene(device);
5102         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5103         if(SUCCEEDED(hr))
5104         {
5105             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5106             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5107
5108             hr = IDirect3DDevice9_EndScene(device);
5109             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5110         }
5111
5112         color = getPixelColor(device, 360, 240);
5113         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1),
5114                 "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
5115
5116         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5117         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5118
5119         IDirect3DPixelShader9_Release(shader_dp2add_sat);
5120     } else {
5121         skip("dp2add shader creation failed\n");
5122     }
5123
5124     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5125     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5126 }
5127
5128 static void cnd_test(IDirect3DDevice9 *device)
5129 {
5130     IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
5131     IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
5132     HRESULT hr;
5133     DWORD color;
5134     /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
5135      * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
5136      * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
5137      */
5138     DWORD shader_code_11[] =  {
5139         0xffff0101,                                                                 /* ps_1_1               */
5140         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5141         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5142         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, ???(t0)      */
5143         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5144         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5145         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5146         0x0000ffff                                                                  /* end                  */
5147     };
5148     DWORD shader_code_12[] =  {
5149         0xffff0102,                                                                 /* ps_1_2               */
5150         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5151         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5152         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5153         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3 r1, r0, c0       */
5154         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5155         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5156         0x0000ffff                                                                  /* end                  */
5157     };
5158     DWORD shader_code_13[] =  {
5159         0xffff0103,                                                                 /* ps_1_3               */
5160         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,     /* def c0, 1, 0, 0, 0   */
5161         0x00000040, 0xb00f0000,                                                     /* texcoord t0          */
5162         0x00000001, 0x800f0000, 0xb0e40000,                                         /* mov r0, t0           */
5163         0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000,                             /* dp3, r1, r0, c0      */
5164         0x00000001, 0x80080000, 0x80ff0001,                                         /* mov r0.a, r1.a       */
5165         0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0.a, c1, c2 */
5166         0x0000ffff                                                                  /* end                  */
5167     };
5168     DWORD shader_code_14[] =  {
5169         0xffff0104,                                                                 /* ps_1_3               */
5170         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,     /* def c0, 0, 0, 0, 1   */
5171         0x00000040, 0x80070000, 0xb0e40000,                                         /* texcrd r0, t0        */
5172         0x00000001, 0x80080000, 0xa0ff0000,                                         /* mov r0.a, c0.a       */
5173         0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002,                 /* cnd r0, r0, c1, c2   */
5174         0x0000ffff                                                                  /* end                  */
5175     };
5176
5177     /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
5178      * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
5179      * set by the compiler, it was added manually after compilation. Note that the COISSUE
5180      * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
5181      * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
5182      * good enough.
5183      *
5184      * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
5185      * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
5186      * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
5187      * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
5188      */
5189     DWORD shader_code_11_coissue[] =  {
5190         0xffff0101,                                                             /* ps_1_1                   */
5191         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5192         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5193         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5194         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5195         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5196         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5197         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5198         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5199         /* 0x40000000 = D3DSI_COISSUE */
5200         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5201         0x0000ffff                                                              /* end                      */
5202     };
5203     DWORD shader_code_12_coissue[] =  {
5204         0xffff0102,                                                             /* ps_1_2                   */
5205         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5206         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5207         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5208         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5209         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5210         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5211         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5212         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5213         /* 0x40000000 = D3DSI_COISSUE */
5214         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5215         0x0000ffff                                                              /* end                      */
5216     };
5217     DWORD shader_code_13_coissue[] =  {
5218         0xffff0103,                                                             /* ps_1_3                   */
5219         0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0       */
5220         0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
5221         0x00000040, 0xb00f0000,                                                 /* texcoord t0              */
5222         0x00000001, 0x800f0000, 0xb0e40000,                                     /* mov r0, t0               */
5223         0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003,                         /* sub r0, r0, c3           */
5224         0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000,                         /* add r1, c0, c0           */
5225         0x00000008, 0x800f0001, 0x80e40000, 0x80e40001,                         /* dp3, r1, r0, r1          */
5226         0x00000001, 0x80080000, 0x80ff0001,                                     /* mov r0.a, r1.a           */
5227         /* 0x40000000 = D3DSI_COISSUE */
5228         0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0.a, c1, c2 */
5229         0x0000ffff                                                              /* end                      */
5230     };
5231     /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
5232      * compare against 0.5
5233      */
5234     DWORD shader_code_14_coissue[] =  {
5235         0xffff0104,                                                             /* ps_1_4                   */
5236         0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1       */
5237         0x00000040, 0x80070000, 0xb0e40000,                                     /* texcrd r0, t0            */
5238         0x00000001, 0x80080000, 0xa0ff0000,                                     /* mov r0.a, c0.a           */
5239         /* 0x40000000 = D3DSI_COISSUE */
5240         0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002,             /* cnd r0.xyz, r0, c1, c2   */
5241         0x0000ffff                                                              /* end                      */
5242     };
5243     float quad1[] = {
5244         -1.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5245          0.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5246         -1.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5247          0.0,    0.0,   0.1,     1.0,    1.0,    0.0
5248     };
5249     float quad2[] = {
5250          0.0,   -1.0,   0.1,     0.0,    0.0,    1.0,
5251          1.0,   -1.0,   0.1,     1.0,    0.0,    1.0,
5252          0.0,    0.0,   0.1,     0.0,    1.0,    0.0,
5253          1.0,    0.0,   0.1,     1.0,    1.0,    0.0
5254     };
5255     float quad3[] = {
5256          0.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5257          1.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5258          0.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5259          1.0,    1.0,   0.1,     1.0,    1.0,    0.0
5260     };
5261     float quad4[] = {
5262         -1.0,    0.0,   0.1,     0.0,    0.0,    1.0,
5263          0.0,    0.0,   0.1,     1.0,    0.0,    1.0,
5264         -1.0,    1.0,   0.1,     0.0,    1.0,    0.0,
5265          0.0,    1.0,   0.1,     1.0,    1.0,    0.0
5266     };
5267     float test_data_c1[4] = {  0.0, 0.0, 0.0, 0.0};
5268     float test_data_c2[4] = {  1.0, 1.0, 1.0, 1.0};
5269     float test_data_c1_coi[4] = {  0.0, 1.0, 0.0, 0.0};
5270     float test_data_c2_coi[4] = {  1.0, 0.0, 1.0, 1.0};
5271
5272     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5273     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5274
5275     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
5276     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5277     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
5278     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5279     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
5280     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5281     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
5282     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5283     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
5284     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5285     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
5286     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5287     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
5288     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5289     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
5290     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5291
5292     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
5293     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5294     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
5295     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5296     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5297     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
5298
5299     hr = IDirect3DDevice9_BeginScene(device);
5300     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5301     if(SUCCEEDED(hr))
5302     {
5303         hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
5304         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5305         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5306         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5307
5308         hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
5309         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5310         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5311         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5312
5313         hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
5314         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5315         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5316         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5317
5318         hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
5319         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5320         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5321         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5322
5323         hr = IDirect3DDevice9_EndScene(device);
5324         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5325     }
5326
5327     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5328     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5329
5330     /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
5331     color = getPixelColor(device, 158, 118);
5332     ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
5333     color = getPixelColor(device, 162, 118);
5334     ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
5335     color = getPixelColor(device, 158, 122);
5336     ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
5337     color = getPixelColor(device, 162, 122);
5338     ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
5339
5340     /* 1.1 shader. All 3 components get set, based on the .w comparison */
5341     color = getPixelColor(device, 158, 358);
5342     ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
5343     color = getPixelColor(device, 162, 358);
5344     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5345         "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
5346     color = getPixelColor(device, 158, 362);
5347     ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
5348     color = getPixelColor(device, 162, 362);
5349     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5350         "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
5351
5352     /* 1.2 shader */
5353     color = getPixelColor(device, 478, 358);
5354     ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
5355     color = getPixelColor(device, 482, 358);
5356     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5357         "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
5358     color = getPixelColor(device, 478, 362);
5359     ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
5360     color = getPixelColor(device, 482, 362);
5361     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5362         "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
5363
5364     /* 1.3 shader */
5365     color = getPixelColor(device, 478, 118);
5366     ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
5367     color = getPixelColor(device, 482, 118);
5368     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5369         "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
5370     color = getPixelColor(device, 478, 122);
5371     ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
5372     color = getPixelColor(device, 482, 122);
5373     ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
5374         "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
5375
5376     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5377     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5378
5379     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
5380     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5381     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
5382     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5383     hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
5384     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5385
5386     hr = IDirect3DDevice9_BeginScene(device);
5387     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5388     if(SUCCEEDED(hr))
5389     {
5390         hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
5391         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5392         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5393         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5394
5395         hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
5396         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5397         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5398         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5399
5400         hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
5401         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5402         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
5403         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5404
5405         hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
5406         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5407         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5408         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5409
5410         hr = IDirect3DDevice9_EndScene(device);
5411         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5412     }
5413
5414     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5415     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5416
5417     /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
5418      * that we swapped the values in c1 and c2 to make the other tests return some color
5419      */
5420     color = getPixelColor(device, 158, 118);
5421     ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
5422     color = getPixelColor(device, 162, 118);
5423     ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
5424     color = getPixelColor(device, 158, 122);
5425     ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
5426     color = getPixelColor(device, 162, 122);
5427     ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
5428
5429     /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
5430      * (The Win7 nvidia driver always selects c2)
5431      */
5432     color = getPixelColor(device, 158, 358);
5433     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5434         "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
5435     color = getPixelColor(device, 162, 358);
5436     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5437         "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
5438     color = getPixelColor(device, 158, 362);
5439     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5440         "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
5441     color = getPixelColor(device, 162, 362);
5442     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5443         "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
5444
5445     /* 1.2 shader */
5446     color = getPixelColor(device, 478, 358);
5447     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5448         "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5449     color = getPixelColor(device, 482, 358);
5450     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5451         "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5452     color = getPixelColor(device, 478, 362);
5453     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5454         "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5455     color = getPixelColor(device, 482, 362);
5456     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5457         "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5458
5459     /* 1.3 shader */
5460     color = getPixelColor(device, 478, 118);
5461     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5462         "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5463     color = getPixelColor(device, 482, 118);
5464     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5465         "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5466     color = getPixelColor(device, 478, 122);
5467     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5468         "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5469     color = getPixelColor(device, 482, 122);
5470     ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x00ff00ff, 1),
5471         "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5472
5473     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5474     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5475
5476     IDirect3DPixelShader9_Release(shader_14_coissue);
5477     IDirect3DPixelShader9_Release(shader_13_coissue);
5478     IDirect3DPixelShader9_Release(shader_12_coissue);
5479     IDirect3DPixelShader9_Release(shader_11_coissue);
5480     IDirect3DPixelShader9_Release(shader_14);
5481     IDirect3DPixelShader9_Release(shader_13);
5482     IDirect3DPixelShader9_Release(shader_12);
5483     IDirect3DPixelShader9_Release(shader_11);
5484 }
5485
5486 static void nested_loop_test(IDirect3DDevice9 *device) {
5487     const DWORD shader_code[] = {
5488         0xffff0300,                                                             /* ps_3_0               */
5489         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1   */
5490         0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5491         0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0  */
5492         0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0           */
5493         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5494         0x0200001b, 0xf0e40800, 0xf0e40000,                                     /* loop aL, i0          */
5495         0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001,                         /* add r0, r0, c1       */
5496         0x0000001d,                                                             /* endloop              */
5497         0x0000001d,                                                             /* endloop              */
5498         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0          */
5499         0x0000ffff                                                              /* end                  */
5500     };
5501     const DWORD vshader_code[] = {
5502         0xfffe0300,                                                             /* vs_3_0               */
5503         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
5504         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
5505         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
5506         0x0000ffff                                                              /* end                  */
5507     };
5508     IDirect3DPixelShader9 *shader;
5509     IDirect3DVertexShader9 *vshader;
5510     HRESULT hr;
5511     DWORD color;
5512     const float quad[] = {
5513         -1.0,   -1.0,   0.1,
5514          1.0,   -1.0,   0.1,
5515         -1.0,    1.0,   0.1,
5516          1.0,    1.0,   0.1
5517     };
5518
5519     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5520     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5521     hr = IDirect3DDevice9_SetPixelShader(device, shader);
5522     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5523     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5524     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
5525     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5526     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5527     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5528     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5529     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5530     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5531
5532     hr = IDirect3DDevice9_BeginScene(device);
5533     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5534     if(SUCCEEDED(hr))
5535     {
5536         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5537         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5538         hr = IDirect3DDevice9_EndScene(device);
5539         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5540     }
5541
5542     color = getPixelColor(device, 360, 240);
5543     ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5544        "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5545
5546     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5547     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5548
5549     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5550     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5551     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5552     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
5553     IDirect3DPixelShader9_Release(shader);
5554     IDirect3DVertexShader9_Release(vshader);
5555 }
5556
5557 struct varying_test_struct
5558 {
5559     const DWORD             *shader_code;
5560     IDirect3DPixelShader9   *shader;
5561     DWORD                   color, color_rhw;
5562     const char              *name;
5563     BOOL                    todo, todo_rhw;
5564 };
5565
5566 struct hugeVertex
5567 {
5568     float pos_x,        pos_y,      pos_z,      rhw;
5569     float weight_1,     weight_2,   weight_3,   weight_4;
5570     float index_1,      index_2,    index_3,    index_4;
5571     float normal_1,     normal_2,   normal_3,   normal_4;
5572     float fog_1,        fog_2,      fog_3,      fog_4;
5573     float texcoord_1,   texcoord_2, texcoord_3, texcoord_4;
5574     float tangent_1,    tangent_2,  tangent_3,  tangent_4;
5575     float binormal_1,   binormal_2, binormal_3, binormal_4;
5576     float depth_1,      depth_2,    depth_3,    depth_4;
5577     DWORD diffuse, specular;
5578 };
5579
5580 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5581     /* dcl_position: fails to compile */
5582     const DWORD blendweight_code[] = {
5583         0xffff0300,                             /* ps_3_0                   */
5584         0x0200001f, 0x80000001, 0x900f0000,     /* dcl_blendweight, v0      */
5585         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5586         0x0000ffff                              /* end                      */
5587     };
5588     const DWORD blendindices_code[] = {
5589         0xffff0300,                             /* ps_3_0                   */
5590         0x0200001f, 0x80000002, 0x900f0000,     /* dcl_blendindices, v0     */
5591         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5592         0x0000ffff                              /* end                      */
5593     };
5594     const DWORD normal_code[] = {
5595         0xffff0300,                             /* ps_3_0                   */
5596         0x0200001f, 0x80000003, 0x900f0000,     /* dcl_normal, v0           */
5597         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5598         0x0000ffff                              /* end                      */
5599     };
5600     /* psize: fails? */
5601     const DWORD texcoord0_code[] = {
5602         0xffff0300,                             /* ps_3_0                   */
5603         0x0200001f, 0x80000005, 0x900f0000,     /* dcl_texcoord0, v0        */
5604         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5605         0x0000ffff                              /* end                      */
5606     };
5607     const DWORD tangent_code[] = {
5608         0xffff0300,                             /* ps_3_0                   */
5609         0x0200001f, 0x80000006, 0x900f0000,     /* dcl_tangent, v0          */
5610         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5611         0x0000ffff                              /* end                      */
5612     };
5613     const DWORD binormal_code[] = {
5614         0xffff0300,                             /* ps_3_0                   */
5615         0x0200001f, 0x80000007, 0x900f0000,     /* dcl_binormal, v0         */
5616         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5617         0x0000ffff                              /* end                      */
5618     };
5619     /* tessfactor: fails */
5620     /* positiont: fails */
5621     const DWORD color_code[] = {
5622         0xffff0300,                             /* ps_3_0                   */
5623         0x0200001f, 0x8000000a, 0x900f0000,     /* dcl_color0, v0           */
5624         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5625         0x0000ffff                              /* end                      */
5626     };
5627     const DWORD fog_code[] = {
5628         0xffff0300,                             /* ps_3_0                   */
5629         0x0200001f, 0x8000000b, 0x900f0000,     /* dcl_fog, v0              */
5630         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5631         0x0000ffff                              /* end                      */
5632     };
5633     const DWORD depth_code[] = {
5634         0xffff0300,                             /* ps_3_0                   */
5635         0x0200001f, 0x8000000c, 0x900f0000,     /* dcl_depth, v0            */
5636         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5637         0x0000ffff                              /* end                      */
5638     };
5639     const DWORD specular_code[] = {
5640         0xffff0300,                             /* ps_3_0                   */
5641         0x0200001f, 0x8001000a, 0x900f0000,     /* dcl_color1, v0           */
5642         0x02000001, 0x800f0800, 0x90e40000,     /* mov oC0, v0              */
5643         0x0000ffff                              /* end                      */
5644     };
5645     /* sample: fails */
5646
5647     struct varying_test_struct tests[] = {
5648        {blendweight_code,       NULL,       0x00000000,     0x00191919,     "blendweight"   ,   FALSE,  TRUE  },
5649        {blendindices_code,      NULL,       0x00000000,     0x00000000,     "blendindices"  ,   FALSE,  FALSE },
5650        {normal_code,            NULL,       0x00000000,     0x004c4c4c,     "normal"        ,   FALSE,  TRUE  },
5651        /* Why does dx not forward the texcoord? */
5652        {texcoord0_code,         NULL,       0x00000000,     0x00808c8c,     "texcoord0"     ,   FALSE,  FALSE },
5653        {tangent_code,           NULL,       0x00000000,     0x00999999,     "tangent"       ,   FALSE,  TRUE  },
5654        {binormal_code,          NULL,       0x00000000,     0x00b2b2b2,     "binormal"      ,   FALSE,  TRUE  },
5655        {color_code,             NULL,       0x00e6e6e6,     0x00e6e6e6,     "color"         ,   FALSE,  FALSE },
5656        {fog_code,               NULL,       0x00000000,     0x00666666,     "fog"           ,   FALSE,  TRUE  },
5657        {depth_code,             NULL,       0x00000000,     0x00cccccc,     "depth"         ,   FALSE,  TRUE  },
5658        {specular_code,          NULL,       0x004488ff,     0x004488ff,     "specular"      ,   FALSE,  FALSE }
5659     };
5660     /* Declare a monster vertex type :-) */
5661     static const D3DVERTEXELEMENT9 decl_elements[] = {
5662         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
5663         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5664         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5665         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5666         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5667         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5668         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5669         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5670         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5671         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5672         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5673         D3DDECL_END()
5674     };
5675     static const D3DVERTEXELEMENT9 decl_elements2[] = {
5676         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
5677         {0,  16,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT,    0},
5678         {0,  32,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES,   0},
5679         {0,  48,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,         0},
5680         {0,  64,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG,            0},
5681         {0,  80,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
5682         {0,  96,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,        0},
5683         {0, 112,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL,       0},
5684         {0, 128,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH,          0},
5685         {0, 144,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
5686         {0, 148,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          1},
5687         D3DDECL_END()
5688     };
5689     struct hugeVertex data[4] = {
5690         {
5691             -1.0,   -1.0,   0.1,    1.0,
5692              0.1,    0.1,   0.1,    0.1,
5693              0.2,    0.2,   0.2,    0.2,
5694              0.3,    0.3,   0.3,    0.3,
5695              0.4,    0.4,   0.4,    0.4,
5696              0.50,   0.55,  0.55,   0.55,
5697              0.6,    0.6,   0.6,    0.7,
5698              0.7,    0.7,   0.7,    0.6,
5699              0.8,    0.8,   0.8,    0.8,
5700              0xe6e6e6e6, /* 0.9 * 256 */
5701              0x224488ff  /* Nothing special */
5702         },
5703         {
5704              1.0,   -1.0,   0.1,    1.0,
5705              0.1,    0.1,   0.1,    0.1,
5706              0.2,    0.2,   0.2,    0.2,
5707              0.3,    0.3,   0.3,    0.3,
5708              0.4,    0.4,   0.4,    0.4,
5709              0.50,   0.55,  0.55,   0.55,
5710              0.6,    0.6,   0.6,    0.7,
5711              0.7,    0.7,   0.7,    0.6,
5712              0.8,    0.8,   0.8,    0.8,
5713              0xe6e6e6e6, /* 0.9 * 256 */
5714              0x224488ff /* Nothing special */
5715         },
5716         {
5717             -1.0,    1.0,   0.1,    1.0,
5718              0.1,    0.1,   0.1,    0.1,
5719              0.2,    0.2,   0.2,    0.2,
5720              0.3,    0.3,   0.3,    0.3,
5721              0.4,    0.4,   0.4,    0.4,
5722              0.50,   0.55,  0.55,   0.55,
5723              0.6,    0.6,   0.6,    0.7,
5724              0.7,    0.7,   0.7,    0.6,
5725              0.8,    0.8,   0.8,    0.8,
5726              0xe6e6e6e6, /* 0.9 * 256 */
5727              0x224488ff /* Nothing special */
5728         },
5729         {
5730              1.0,    1.0,   0.1,    1.0,
5731              0.1,    0.1,   0.1,    0.1,
5732              0.2,    0.2,   0.2,    0.2,
5733              0.3,    0.3,   0.3,    0.3,
5734              0.4,    0.4,   0.4,    0.4,
5735              0.50,   0.55,  0.55,   0.55,
5736              0.6,    0.6,   0.6,    0.7,
5737              0.7,    0.7,   0.7,    0.6,
5738              0.8,    0.8,   0.8,    0.8,
5739              0xe6e6e6e6, /* 0.9 * 256 */
5740              0x224488ff /* Nothing special */
5741         },
5742     };
5743     struct hugeVertex data2[4];
5744     IDirect3DVertexDeclaration9 *decl;
5745     IDirect3DVertexDeclaration9 *decl2;
5746     HRESULT hr;
5747     unsigned int i;
5748     DWORD color, r, g, b, r_e, g_e, b_e;
5749     BOOL drawok;
5750
5751     memcpy(data2, data, sizeof(data2));
5752     data2[0].pos_x = 0;     data2[0].pos_y = 0;
5753     data2[1].pos_x = 640;   data2[1].pos_y = 0;
5754     data2[2].pos_x = 0;     data2[2].pos_y = 480;
5755     data2[3].pos_x = 640;   data2[3].pos_y = 480;
5756
5757     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5758     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5759     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5760     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5761     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5762     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5763
5764     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5765     {
5766         hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5767         ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5768            tests[i].name, hr);
5769     }
5770
5771     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5772     {
5773         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5774         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5775
5776         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5777         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5778
5779         hr = IDirect3DDevice9_BeginScene(device);
5780         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5781         drawok = FALSE;
5782         if(SUCCEEDED(hr))
5783         {
5784             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5785             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5786             drawok = SUCCEEDED(hr);
5787             hr = IDirect3DDevice9_EndScene(device);
5788             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5789         }
5790
5791         /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5792          * the failure and do not check the color if it failed
5793          */
5794         if(!drawok) {
5795             continue;
5796         }
5797
5798         color = getPixelColor(device, 360, 240);
5799         r = color & 0x00ff0000 >> 16;
5800         g = color & 0x0000ff00 >>  8;
5801         b = color & 0x000000ff;
5802         r_e = tests[i].color & 0x00ff0000 >> 16;
5803         g_e = tests[i].color & 0x0000ff00 >>  8;
5804         b_e = tests[i].color & 0x000000ff;
5805
5806         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5807         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5808
5809         if(tests[i].todo) {
5810             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5811                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5812                          tests[i].name, color, tests[i].color);
5813         } else {
5814             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5815                "Test %s returned color 0x%08x, expected 0x%08x\n",
5816                tests[i].name, color, tests[i].color);
5817         }
5818     }
5819
5820     hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5821     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5822     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5823     {
5824         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5825         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5826
5827         IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5828         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5829
5830         hr = IDirect3DDevice9_BeginScene(device);
5831         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5832         if(SUCCEEDED(hr))
5833         {
5834             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5835             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5836             hr = IDirect3DDevice9_EndScene(device);
5837             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5838         }
5839
5840         color = getPixelColor(device, 360, 240);
5841         r = color & 0x00ff0000 >> 16;
5842         g = color & 0x0000ff00 >>  8;
5843         b = color & 0x000000ff;
5844         r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5845         g_e = tests[i].color_rhw & 0x0000ff00 >>  8;
5846         b_e = tests[i].color_rhw & 0x000000ff;
5847
5848         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5849         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5850
5851         if(tests[i].todo_rhw) {
5852             /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5853              * pipeline
5854              */
5855             todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5856                          "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5857                          tests[i].name, color, tests[i].color_rhw);
5858         } else {
5859             ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5860                "Test %s returned color 0x%08x, expected 0x%08x\n",
5861                tests[i].name, color, tests[i].color_rhw);
5862         }
5863     }
5864
5865     for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5866     {
5867         IDirect3DPixelShader9_Release(tests[i].shader);
5868     }
5869
5870     IDirect3DVertexDeclaration9_Release(decl2);
5871     IDirect3DVertexDeclaration9_Release(decl);
5872 }
5873
5874 static void test_compare_instructions(IDirect3DDevice9 *device)
5875 {
5876     DWORD shader_sge_vec_code[] = {
5877         0xfffe0101,                                         /* vs_1_1                   */
5878         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5879         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5880         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5881         0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* sge oD0, r0, c1          */
5882         0x0000ffff                                          /* end                      */
5883     };
5884     DWORD shader_slt_vec_code[] = {
5885         0xfffe0101,                                         /* vs_1_1                   */
5886         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5887         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5888         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5889         0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001,     /* slt oD0, r0, c1          */
5890         0x0000ffff                                          /* end                      */
5891     };
5892     DWORD shader_sge_scalar_code[] = {
5893         0xfffe0101,                                         /* vs_1_1                   */
5894         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5895         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5896         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5897         0x0000000d, 0xd0010000, 0x80000000, 0xa0550001,     /* slt oD0.r, r0.r, c1.b    */
5898         0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001,     /* slt oD0.g, r0.g, c1.r    */
5899         0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001,     /* slt oD0.b, r0.b, c1.g    */
5900         0x0000ffff                                          /* end                      */
5901     };
5902     DWORD shader_slt_scalar_code[] = {
5903         0xfffe0101,                                         /* vs_1_1                   */
5904         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0          */
5905         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0             */
5906         0x00000001, 0x800f0000, 0xa0e40000,                 /* mov r0, c0               */
5907         0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001,     /* slt oD0.r, r0.r, c1.b    */
5908         0x0000000c, 0xd0020000, 0x80550000, 0xa0000001,     /* slt oD0.g, r0.g, c1.r    */
5909         0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001,     /* slt oD0.b, r0.b, c1.g    */
5910         0x0000ffff                                          /* end                      */
5911     };
5912     IDirect3DVertexShader9 *shader_sge_vec;
5913     IDirect3DVertexShader9 *shader_slt_vec;
5914     IDirect3DVertexShader9 *shader_sge_scalar;
5915     IDirect3DVertexShader9 *shader_slt_scalar;
5916     HRESULT hr, color;
5917     float quad1[] =  {
5918         -1.0,   -1.0,   0.1,
5919          0.0,   -1.0,   0.1,
5920         -1.0,    0.0,   0.1,
5921          0.0,    0.0,   0.1
5922     };
5923     float quad2[] =  {
5924          0.0,   -1.0,   0.1,
5925          1.0,   -1.0,   0.1,
5926          0.0,    0.0,   0.1,
5927          1.0,    0.0,   0.1
5928     };
5929     float quad3[] =  {
5930         -1.0,    0.0,   0.1,
5931          0.0,    0.0,   0.1,
5932         -1.0,    1.0,   0.1,
5933          0.0,    1.0,   0.1
5934     };
5935     float quad4[] =  {
5936          0.0,    0.0,   0.1,
5937          1.0,    0.0,   0.1,
5938          0.0,    1.0,   0.1,
5939          1.0,    1.0,   0.1
5940     };
5941     const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5942     const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5943
5944     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5945     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5946
5947     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5948     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5949     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5950     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5951     hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5952     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5953     hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5954     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5955     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5956     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5957     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5958     ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5959     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5960     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5961
5962     hr = IDirect3DDevice9_BeginScene(device);
5963     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5964     if(SUCCEEDED(hr))
5965     {
5966         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5967         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5968         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5969         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5970
5971         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5972         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5973         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,  quad2, sizeof(float) * 3);
5974         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5975
5976         hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5977         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5978         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5979         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5980
5981         hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5982         ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5983
5984         hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5985         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5986         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5987         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5988
5989         hr = IDirect3DDevice9_EndScene(device);
5990         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5991     }
5992
5993     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5994     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5995
5996     color = getPixelColor(device, 160, 360);
5997     ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5998     color = getPixelColor(device, 480, 360);
5999     ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
6000     color = getPixelColor(device, 160, 120);
6001     ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
6002     color = getPixelColor(device, 480, 160);
6003     ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
6004
6005     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6006     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6007
6008     IDirect3DVertexShader9_Release(shader_sge_vec);
6009     IDirect3DVertexShader9_Release(shader_slt_vec);
6010     IDirect3DVertexShader9_Release(shader_sge_scalar);
6011     IDirect3DVertexShader9_Release(shader_slt_scalar);
6012 }
6013
6014 static void test_vshader_input(IDirect3DDevice9 *device)
6015 {
6016     DWORD swapped_shader_code_3[] = {
6017         0xfffe0300,                                         /* vs_3_0               */
6018         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6019         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6020         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6021         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6022         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6023         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6024         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6025         0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6026         0x0000ffff                                          /* end                  */
6027     };
6028     DWORD swapped_shader_code_1[] = {
6029         0xfffe0101,                                         /* vs_1_1               */
6030         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6031         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6032         0x0000001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6033         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6034         0x00000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6035         0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6036         0x0000ffff                                          /* end                  */
6037     };
6038     DWORD swapped_shader_code_2[] = {
6039         0xfffe0200,                                         /* vs_2_0               */
6040         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6041         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord0 v1     */
6042         0x0200001f, 0x80010005, 0x900f0002,                 /* dcl_texcoord1 v2     */
6043         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov o0, v0           */
6044         0x02000001, 0x800f0001, 0x90e40001,                 /* mov r1, v1           */
6045         0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002,     /* sub o1, r1, v2       */
6046         0x0000ffff                                          /* end                  */
6047     };
6048     DWORD texcoord_color_shader_code_3[] = {
6049         0xfffe0300,                                         /* vs_3_0               */
6050         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6051         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6052         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6053         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6054         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6055         0x02000001, 0xe00f0001, 0x90e40001,                 /* mov o1, v1           */
6056         0x0000ffff                                          /* end                  */
6057     };
6058     DWORD texcoord_color_shader_code_2[] = {
6059         0xfffe0200,                                         /* vs_2_0               */
6060         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6061         0x0200001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6062         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6063         0x02000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6064         0x0000ffff                                          /* end                  */
6065     };
6066     DWORD texcoord_color_shader_code_1[] = {
6067         0xfffe0101,                                         /* vs_1_1               */
6068         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6069         0x0000001f, 0x80000005, 0x900f0001,                 /* dcl_texcoord v1      */
6070         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6071         0x00000001, 0xd00f0000, 0x90e40001,                 /* mov oD0, v1          */
6072         0x0000ffff                                          /* end                  */
6073     };
6074     DWORD color_color_shader_code_3[] = {
6075         0xfffe0300,                                         /* vs_3_0               */
6076         0x0200001f, 0x80000000, 0xe00f0000,                 /* dcl_position o0      */
6077         0x0200001f, 0x8000000a, 0xe00f0001,                 /* dcl_color o1         */
6078         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6079         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6080         0x02000001, 0xe00f0000, 0x90e40000,                 /* mov o0, v0           */
6081         0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001,     /* mul o1, c0, v1       */
6082         0x0000ffff                                          /* end                  */
6083     };
6084     DWORD color_color_shader_code_2[] = {
6085         0xfffe0200,                                         /* vs_2_0               */
6086         0x0200001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6087         0x0200001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6088         0x02000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6089         0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6090         0x0000ffff                                          /* end                  */
6091     };
6092     DWORD color_color_shader_code_1[] = {
6093         0xfffe0101,                                         /* vs_1_1               */
6094         0x0000001f, 0x80000000, 0x900f0000,                 /* dcl_position v0      */
6095         0x0000001f, 0x8000000a, 0x900f0001,                 /* dcl_color v1         */
6096         0x00000001, 0xc00f0000, 0x90e40000,                 /* mov oPos, v0         */
6097         0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001,     /* mul oD0, c0, v1       */
6098         0x0000ffff                                          /* end                  */
6099     };
6100     IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6101     HRESULT hr;
6102     DWORD color;
6103     float quad1[] =  {
6104         -1.0,   -1.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,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6107          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6108     };
6109     float quad2[] =  {
6110          0.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6111          1.0,   -1.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6112          0.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6113          1.0,    0.0,   0.1,    1.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6114     };
6115     float quad3[] =  {
6116         -1.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,    -1.0,   0.0,    0.0,
6117          0.0,    0.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    1.0,     0.0,   0.0,    0.0,
6118         -1.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,    0.0,    -1.0,   1.0,    0.0,
6119          0.0,    1.0,   0.1,   -1.0,    0.0,    0.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6120     };
6121     float quad4[] =  {
6122          0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6123          1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6124          0.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6125          1.0,    1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.5,    0.0,
6126     };
6127     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6128         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6129         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6130         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6131         D3DDECL_END()
6132     };
6133     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6134         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6135         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6136         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6137         D3DDECL_END()
6138     };
6139     static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6140         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6141         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6142         D3DDECL_END()
6143     };
6144     static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6145         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6146         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       1},
6147         {0,  28,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       2},
6148         D3DDECL_END()
6149     };
6150     static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6151         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6152         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,       0},
6153         D3DDECL_END()
6154     };
6155     static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6156         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6157         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6158         D3DDECL_END()
6159     };
6160     static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6161         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6162         {0,  12,  D3DDECLTYPE_UBYTE4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6163         D3DDECL_END()
6164     };
6165     static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6166         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6167         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6168         D3DDECL_END()
6169     };
6170     IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6171     IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6172     unsigned int i;
6173     float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6174     float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6175
6176     struct vertex quad1_color[] =  {
6177        {-1.0,   -1.0,   0.1,    0x00ff8040},
6178        { 0.0,   -1.0,   0.1,    0x00ff8040},
6179        {-1.0,    0.0,   0.1,    0x00ff8040},
6180        { 0.0,    0.0,   0.1,    0x00ff8040}
6181     };
6182     struct vertex quad2_color[] =  {
6183        { 0.0,   -1.0,   0.1,    0x00ff8040},
6184        { 1.0,   -1.0,   0.1,    0x00ff8040},
6185        { 0.0,    0.0,   0.1,    0x00ff8040},
6186        { 1.0,    0.0,   0.1,    0x00ff8040}
6187     };
6188     struct vertex quad3_color[] =  {
6189        {-1.0,    0.0,   0.1,    0x00ff8040},
6190        { 0.0,    0.0,   0.1,    0x00ff8040},
6191        {-1.0,    1.0,   0.1,    0x00ff8040},
6192        { 0.0,    1.0,   0.1,    0x00ff8040}
6193     };
6194     float quad4_color[] =  {
6195          0.0,    0.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6196          1.0,    0.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6197          0.0,    1.0,   0.1,    1.0,    1.0,    0.0,    0.0,
6198          1.0,    1.0,   0.1,    1.0,    1.0,    0.0,    1.0,
6199     };
6200
6201     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6202     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6203     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6204     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6205     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6206     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6207     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6208     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6209
6210     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6211     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6212     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6213     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6214     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6215     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6216     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6217     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6218
6219     for(i = 1; i <= 3; i++) {
6220         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6221         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6222         if(i == 3) {
6223             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6224             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6225         } else if(i == 2){
6226             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6227             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6228         } else if(i == 1) {
6229             hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6230             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6231         }
6232
6233         hr = IDirect3DDevice9_BeginScene(device);
6234         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6235         if(SUCCEEDED(hr))
6236         {
6237             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6238             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6239
6240             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6241             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6242             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6243             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6244
6245             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6246             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6247             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6248             if(i == 3 || i == 2) {
6249                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6250             } else if(i == 1) {
6251                 /* Succeeds or fails, depending on SW or HW vertex processing */
6252                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6253             }
6254
6255             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6256             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6257             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6258             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6259
6260             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6261             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6262             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6263             if(i == 3 || i == 2) {
6264                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6265             } else if(i == 1) {
6266                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6267             }
6268
6269             hr = IDirect3DDevice9_EndScene(device);
6270             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6271         }
6272
6273         if(i == 3 || i == 2) {
6274             color = getPixelColor(device, 160, 360);
6275             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6276                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6277
6278             /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6279             color = getPixelColor(device, 480, 360);
6280             ok(color == 0x00FFFF00 || color ==0x00FF0000,
6281                "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6282             color = getPixelColor(device, 160, 120);
6283             /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6284             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6285                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6286
6287             color = getPixelColor(device, 480, 160);
6288             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6289         } else if(i == 1) {
6290             color = getPixelColor(device, 160, 360);
6291             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6292                "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6293             color = getPixelColor(device, 480, 360);
6294             /* Accept the clear color as well in this case, since SW VP returns an error */
6295             ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6296             color = getPixelColor(device, 160, 120);
6297             ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6298                "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6299             color = getPixelColor(device, 480, 160);
6300             ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6301         }
6302
6303         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6304         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6305
6306         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6307         ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6308
6309         /* Now find out if the whole streams are re-read, or just the last active value for the
6310          * vertices is used.
6311          */
6312         hr = IDirect3DDevice9_BeginScene(device);
6313         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6314         if(SUCCEEDED(hr))
6315         {
6316             float quad1_modified[] =  {
6317                 -1.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,     0.0,   0.0,    0.0,
6318                  0.0,   -1.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,    -1.0,   0.0,    0.0,
6319                 -1.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,    0.0,     0.0,  -1.0,    0.0,
6320                  0.0,    0.0,   0.1,    1.0,    0.0,    1.0,    0.0,   -1.0,    -1.0,  -1.0,    0.0,
6321             };
6322             float quad2_modified[] =  {
6323                  0.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6324                  1.0,   -1.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6325                  0.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6326                  1.0,    0.0,   0.1,    0.0,    0.0,    0.0,    0.0,    0.0,     0.0,   0.0,    0.0,
6327             };
6328
6329             hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6330             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6331
6332             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6333             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6334             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6335             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6336
6337             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6338             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6339             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6340             if(i == 3 || i == 2) {
6341                 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6342             } else if(i == 1) {
6343                 /* Succeeds or fails, depending on SW or HW vertex processing */
6344                 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6345             }
6346
6347             hr = IDirect3DDevice9_EndScene(device);
6348             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6349         }
6350
6351         color = getPixelColor(device, 480, 350);
6352         /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6353          * as well.
6354          *
6355          * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6356          * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6357          * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6358          * refrast's result.
6359          *
6360          * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6361          */
6362         ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6363            "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6364
6365         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6366         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6367
6368         IDirect3DDevice9_SetVertexShader(device, NULL);
6369         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6370
6371         IDirect3DVertexShader9_Release(swapped_shader);
6372     }
6373
6374     for(i = 1; i <= 3; i++) {
6375         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6376         ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
6377         if(i == 3) {
6378             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6379             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6380             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6381             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6382         } else if(i == 2){
6383             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6384             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6385             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6386             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6387         } else if(i == 1) {
6388             hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6389             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6390             hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6391             ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6392         }
6393
6394         hr = IDirect3DDevice9_BeginScene(device);
6395         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6396         if(SUCCEEDED(hr))
6397         {
6398             hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6399             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6400             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6401             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6402             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6403             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6404
6405             hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6406             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6407
6408             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6409             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6410             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6411             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6412             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6413             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6414
6415             hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6416             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6417             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6418             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6419             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6420             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6421
6422             hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6423             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6424             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6425             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6426
6427             hr = IDirect3DDevice9_EndScene(device);
6428             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6429         }
6430         IDirect3DDevice9_SetVertexShader(device, NULL);
6431         IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6432
6433         color = getPixelColor(device, 160, 360);
6434         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6435            "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6436         color = getPixelColor(device, 480, 360);
6437         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6438            "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6439         color = getPixelColor(device, 160, 120);
6440         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6441            "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6442         color = getPixelColor(device, 480, 160);
6443         ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6444            "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6445
6446         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6447         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6448
6449         IDirect3DVertexShader9_Release(texcoord_color_shader);
6450         IDirect3DVertexShader9_Release(color_color_shader);
6451     }
6452
6453     IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6454     IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6455     IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6456     IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6457
6458     IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6459     IDirect3DVertexDeclaration9_Release(decl_color_color);
6460     IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6461     IDirect3DVertexDeclaration9_Release(decl_color_float);
6462 }
6463
6464 static void srgbtexture_test(IDirect3DDevice9 *device)
6465 {
6466     /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6467      * texture stage state to render a quad using that texture.  The resulting
6468      * color components should be 0x36 (~ 0.21), per this formula:
6469      *    linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6470      * This is true where srgb_color > 0.04045.
6471      */
6472     IDirect3D9 *d3d = NULL;
6473     HRESULT hr;
6474     LPDIRECT3DTEXTURE9 texture = NULL;
6475     LPDIRECT3DSURFACE9 surface = NULL;
6476     D3DLOCKED_RECT lr;
6477     DWORD color;
6478     float quad[] = {
6479         -1.0,       1.0,       0.0,     0.0,    0.0,
6480          1.0,       1.0,       0.0,     1.0,    0.0,
6481         -1.0,      -1.0,       0.0,     0.0,    1.0,
6482          1.0,      -1.0,       0.0,     1.0,    1.0,
6483     };
6484
6485
6486     memset(&lr, 0, sizeof(lr));
6487     IDirect3DDevice9_GetDirect3D(device, &d3d);
6488     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6489                                     D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6490                                     D3DFMT_A8R8G8B8) != D3D_OK) {
6491         skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6492         goto out;
6493     }
6494
6495     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6496                                         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6497                                         &texture, NULL);
6498     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6499     if(!texture) {
6500         skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6501         goto out;
6502     }
6503     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6504     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6505
6506     fill_surface(surface, 0xff7f7f7f);
6507     IDirect3DSurface9_Release(surface);
6508
6509     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6510     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6511     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6512     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6513
6514     hr = IDirect3DDevice9_BeginScene(device);
6515     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6516     if(SUCCEEDED(hr))
6517     {
6518         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6519         ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6520
6521         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6522         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6523
6524
6525         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6526         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6527
6528         hr = IDirect3DDevice9_EndScene(device);
6529         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6530     }
6531
6532     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6533     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6534     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6535     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6536
6537     color = getPixelColor(device, 320, 240);
6538     ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6539
6540     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6541     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6542
6543 out:
6544     if(texture) IDirect3DTexture9_Release(texture);
6545     IDirect3D9_Release(d3d);
6546 }
6547
6548 static void shademode_test(IDirect3DDevice9 *device)
6549 {
6550     /* Render a quad and try all of the different fixed function shading models. */
6551     HRESULT hr;
6552     DWORD color0, color1;
6553     DWORD color0_gouraud = 0, color1_gouraud = 0;
6554     DWORD shademode = D3DSHADE_FLAT;
6555     DWORD primtype = D3DPT_TRIANGLESTRIP;
6556     LPVOID data = NULL;
6557     LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6558     LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6559     UINT i, j;
6560     struct vertex quad_strip[] =
6561     {
6562         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6563         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6564         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6565         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6566     };
6567     struct vertex quad_list[] =
6568     {
6569         {-1.0f, -1.0f,  0.0f, 0xffff0000  },
6570         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6571         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6572
6573         {-1.0f,  1.0f,  0.0f, 0xff00ff00  },
6574         { 1.0f, -1.0f,  0.0f, 0xff0000ff  },
6575         { 1.0f,  1.0f,  0.0f, 0xffffffff  }
6576     };
6577
6578     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6579                                              0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6580     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6581     if (FAILED(hr)) goto bail;
6582
6583     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6584                                              0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6585     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6586     if (FAILED(hr)) goto bail;
6587
6588     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6589     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6590
6591     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6592     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6593
6594     hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
6595     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6596     memcpy(data, quad_strip, sizeof(quad_strip));
6597     hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6598     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6599
6600     hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
6601     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6602     memcpy(data, quad_list, sizeof(quad_list));
6603     hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6604     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6605
6606     /* Try it first with a TRIANGLESTRIP.  Do it with different geometry because
6607      * the color fixups we have to do for FLAT shading will be dependent on that. */
6608     hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6609     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6610
6611     /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6612     for (j=0; j<2; j++) {
6613
6614         /* Inner loop just changes the D3DRS_SHADEMODE */
6615         for (i=0; i<3; i++) {
6616             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6617             ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6618
6619             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6620             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6621
6622             hr = IDirect3DDevice9_BeginScene(device);
6623             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6624             if(SUCCEEDED(hr))
6625             {
6626                 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6627                 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6628
6629                 hr = IDirect3DDevice9_EndScene(device);
6630                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6631             }
6632
6633             /* Sample two spots from the output */
6634             color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6635             color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6636             switch(shademode) {
6637                 case D3DSHADE_FLAT:
6638                     /* Should take the color of the first vertex of each triangle */
6639                     if (0)
6640                     {
6641                         /* This test depends on EXT_provoking_vertex being
6642                          * available. This extension is currently (20090810)
6643                          * not common enough to let the test fail if it isn't
6644                          * present. */
6645                         ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000\n", color0);
6646                         ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00\n", color1);
6647                     }
6648                     shademode = D3DSHADE_GOURAUD;
6649                     break;
6650                 case D3DSHADE_GOURAUD:
6651                     /* Should be an interpolated blend */
6652
6653                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6654                        "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6655                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6656                        "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6657
6658                     color0_gouraud = color0;
6659                     color1_gouraud = color1;
6660
6661                     shademode = D3DSHADE_PHONG;
6662                     break;
6663                 case D3DSHADE_PHONG:
6664                     /* Should be the same as GOURAUD, since no hardware implements this */
6665                     ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6666                        "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6667                     ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6668                        "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6669
6670                     ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6671                             color0_gouraud, color0);
6672                     ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6673                             color1_gouraud, color1);
6674                     break;
6675             }
6676         }
6677
6678         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6679         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6680
6681         /* Now, do it all over again with a TRIANGLELIST */
6682         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6683         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6684         primtype = D3DPT_TRIANGLELIST;
6685         shademode = D3DSHADE_FLAT;
6686     }
6687
6688 bail:
6689     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6690     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6691     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6692     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6693
6694     if (vb_strip)
6695         IDirect3DVertexBuffer9_Release(vb_strip);
6696     if (vb_list)
6697         IDirect3DVertexBuffer9_Release(vb_list);
6698 }
6699
6700 static void alpha_test(IDirect3DDevice9 *device)
6701 {
6702     HRESULT hr;
6703     IDirect3DTexture9 *offscreenTexture;
6704     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6705     DWORD color;
6706
6707     struct vertex quad1[] =
6708     {
6709         {-1.0f, -1.0f,   0.1f,                          0x4000ff00},
6710         {-1.0f,  0.0f,   0.1f,                          0x4000ff00},
6711         { 1.0f, -1.0f,   0.1f,                          0x4000ff00},
6712         { 1.0f,  0.0f,   0.1f,                          0x4000ff00},
6713     };
6714     struct vertex quad2[] =
6715     {
6716         {-1.0f,  0.0f,   0.1f,                          0xc00000ff},
6717         {-1.0f,  1.0f,   0.1f,                          0xc00000ff},
6718         { 1.0f,  0.0f,   0.1f,                          0xc00000ff},
6719         { 1.0f,  1.0f,   0.1f,                          0xc00000ff},
6720     };
6721     static const float composite_quad[][5] = {
6722         { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6723         { 0.0f,  1.0f, 0.1f, 0.0f, 0.0f},
6724         { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6725         { 1.0f,  1.0f, 0.1f, 1.0f, 0.0f},
6726     };
6727
6728     /* Clear the render target with alpha = 0.5 */
6729     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6730     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6731
6732     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6733     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6734
6735     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6736     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6737     if(!backbuffer) {
6738         goto out;
6739     }
6740
6741     hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6742     ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6743     if(!offscreen) {
6744         goto out;
6745     }
6746
6747     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6748     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6749
6750     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6751     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6752     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6753     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6754     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6755     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6756     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6757     ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6759     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6760
6761     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6762     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6763     if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6764
6765         /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6766         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6767         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6768         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6769         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6770         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6771         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6772
6773         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6774         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6775         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6776         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6777         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6778         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6779
6780         /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6781          * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6782          * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6783         hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6784         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6785         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6786         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6787
6788         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6789         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6790         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6791         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6792         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6793         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6794
6795         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6796         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6797         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6798         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6799         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6800         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6801
6802         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6803         ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6804
6805         /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6806          * Disable alpha blending for the final composition
6807          */
6808         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6809         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6810         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6811         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6812
6813         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6814         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6815         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6816         ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6817         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6818         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6819
6820         hr = IDirect3DDevice9_EndScene(device);
6821         ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6822     }
6823
6824     color = getPixelColor(device, 160, 360);
6825     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6826        "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6827
6828     color = getPixelColor(device, 160, 120);
6829     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6830        "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6831
6832     color = getPixelColor(device, 480, 360);
6833     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6834        "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6835
6836     color = getPixelColor(device, 480, 120);
6837     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6838        "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6839
6840     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6841
6842     out:
6843     /* restore things */
6844     if(backbuffer) {
6845         IDirect3DSurface9_Release(backbuffer);
6846     }
6847     if(offscreenTexture) {
6848         IDirect3DTexture9_Release(offscreenTexture);
6849     }
6850     if(offscreen) {
6851         IDirect3DSurface9_Release(offscreen);
6852     }
6853 }
6854
6855 struct vertex_shortcolor {
6856     float x, y, z;
6857     unsigned short r, g, b, a;
6858 };
6859 struct vertex_floatcolor {
6860     float x, y, z;
6861     float r, g, b, a;
6862 };
6863
6864 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6865 {
6866     HRESULT hr;
6867     BOOL s_ok, ub_ok, f_ok;
6868     DWORD color, size, i;
6869     void *data;
6870     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6871         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6872         {0,  12,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6873         D3DDECL_END()
6874     };
6875     static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6876         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6877         {1,   0,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6878         D3DDECL_END()
6879     };
6880     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6881         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6882         {0,  12,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6883         D3DDECL_END()
6884     };
6885     static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6886         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6887         {1,   0,  D3DDECLTYPE_UBYTE4N,  D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6888         D3DDECL_END()
6889     };
6890     static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6891         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6892         {0,  12,  D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6893         D3DDECL_END()
6894     };
6895     static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6896         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
6897         {0,  12,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6898         D3DDECL_END()
6899     };
6900     static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6901         {0,   0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT,      0},
6902         {0,  16,  D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
6903         D3DDECL_END()
6904     };
6905     IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6906     IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6907     IDirect3DVertexBuffer9 *vb, *vb2;
6908     struct vertex quad1[] =                             /* D3DCOLOR */
6909     {
6910         {-1.0f, -1.0f,   0.1f,                          0x00ffff00},
6911         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6912         { 0.0f, -1.0f,   0.1f,                          0x00ffff00},
6913         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6914     };
6915     struct vertex quad2[] =                             /* UBYTE4N */
6916     {
6917         {-1.0f,  0.0f,   0.1f,                          0x00ffff00},
6918         {-1.0f,  1.0f,   0.1f,                          0x00ffff00},
6919         { 0.0f,  0.0f,   0.1f,                          0x00ffff00},
6920         { 0.0f,  1.0f,   0.1f,                          0x00ffff00},
6921     };
6922     struct vertex_shortcolor quad3[] =                  /* short */
6923     {
6924         { 0.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6925         { 0.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6926         { 1.0f, -1.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6927         { 1.0f,  0.0f,   0.1f,                          0x0000, 0x0000, 0xffff, 0xffff},
6928     };
6929     struct vertex_floatcolor quad4[] =
6930     {
6931         { 0.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6932         { 0.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6933         { 1.0f,  0.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6934         { 1.0f,  1.0f,   0.1f,                          1.0, 0.0, 0.0, 0.0},
6935     };
6936     DWORD colors[] = {
6937         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6938         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6939         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6940         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6941         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6942         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6943         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6944         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6945         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6946         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6947         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6948         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6949         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6950         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6951         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6952         0x00ff0000,   0x0000ff00,     0x000000ff,   0x00ffffff,
6953     };
6954     float quads[] = {
6955         -1.0,   -1.0,     0.1,
6956         -1.0,    0.0,     0.1,
6957          0.0,   -1.0,     0.1,
6958          0.0,    0.0,     0.1,
6959
6960          0.0,   -1.0,     0.1,
6961          0.0,    0.0,     0.1,
6962          1.0,   -1.0,     0.1,
6963          1.0,    0.0,     0.1,
6964
6965          0.0,    0.0,     0.1,
6966          0.0,    1.0,     0.1,
6967          1.0,    0.0,     0.1,
6968          1.0,    1.0,     0.1,
6969
6970         -1.0,    0.0,     0.1,
6971         -1.0,    1.0,     0.1,
6972          0.0,    0.0,     0.1,
6973          0.0,    1.0,     0.1
6974     };
6975     struct tvertex quad_transformed[] = {
6976        {  90,    110,     0.1,      2.0,        0x00ffff00},
6977        { 570,    110,     0.1,      2.0,        0x00ffff00},
6978        {  90,    300,     0.1,      2.0,        0x00ffff00},
6979        { 570,    300,     0.1,      2.0,        0x00ffff00}
6980     };
6981     D3DCAPS9 caps;
6982
6983     memset(&caps, 0, sizeof(caps));
6984     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6985     ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6986
6987     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6988     ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6989
6990     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6991     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6992     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6993     ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6994     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6995     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6996     if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6997         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6998         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6999         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
7000         ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7001     } else {
7002         trace("D3DDTCAPS_UBYTE4N not supported\n");
7003         dcl_ubyte_2 = NULL;
7004         dcl_ubyte = NULL;
7005     }
7006     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7007     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7008     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7009     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7010
7011     size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7012     hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7013                                              0, 0, D3DPOOL_MANAGED, &vb, NULL);
7014     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7015
7016     hr = IDirect3DDevice9_BeginScene(device);
7017     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7018     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7019     if(SUCCEEDED(hr)) {
7020         if(dcl_color) {
7021             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7022             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7023             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7024             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7025         }
7026
7027         /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7028          * accepts them, the nvidia driver accepts them all. All those differences even though we're
7029          * using software vertex processing. Doh!
7030          */
7031         if(dcl_ubyte) {
7032             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7033             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7034             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7035             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7036             ub_ok = SUCCEEDED(hr);
7037         }
7038
7039         if(dcl_short) {
7040             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7041             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7042             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7043             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7044             s_ok = SUCCEEDED(hr);
7045         }
7046
7047         if(dcl_float) {
7048             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7049             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7050             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7051             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7052             f_ok = SUCCEEDED(hr);
7053         }
7054
7055         hr = IDirect3DDevice9_EndScene(device);
7056         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7057     }
7058
7059     if(dcl_short) {
7060         color = getPixelColor(device, 480, 360);
7061         ok(color == 0x000000ff || !s_ok,
7062            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7063     }
7064     if(dcl_ubyte) {
7065         color = getPixelColor(device, 160, 120);
7066         ok(color == 0x0000ffff || !ub_ok,
7067            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7068     }
7069     if(dcl_color) {
7070         color = getPixelColor(device, 160, 360);
7071         ok(color == 0x00ffff00,
7072            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7073     }
7074     if(dcl_float) {
7075         color = getPixelColor(device, 480, 120);
7076         ok(color == 0x00ff0000 || !f_ok,
7077            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7078     }
7079     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7080
7081     /* The following test with vertex buffers doesn't serve to find out new information from windows.
7082      * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7083      * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7084      * whether the immediate mode code works
7085      */
7086     f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7087     hr = IDirect3DDevice9_BeginScene(device);
7088     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7089     if(SUCCEEDED(hr)) {
7090         if(dcl_color) {
7091             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
7092             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7093             memcpy(data, quad1, sizeof(quad1));
7094             hr = IDirect3DVertexBuffer9_Unlock(vb);
7095             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7096             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7097             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7098             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7099             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7100             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7101             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7102         }
7103
7104         if(dcl_ubyte) {
7105             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
7106             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7107             memcpy(data, quad2, sizeof(quad2));
7108             hr = IDirect3DVertexBuffer9_Unlock(vb);
7109             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7110             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7111             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7112             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7113             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7114             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7115             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7116                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7117             ub_ok = SUCCEEDED(hr);
7118         }
7119
7120         if(dcl_short) {
7121             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
7122             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7123             memcpy(data, quad3, sizeof(quad3));
7124             hr = IDirect3DVertexBuffer9_Unlock(vb);
7125             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7126             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7127             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7128             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7129             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7130             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7131             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7132                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7133             s_ok = SUCCEEDED(hr);
7134         }
7135
7136         if(dcl_float) {
7137             hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
7138             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7139             memcpy(data, quad4, sizeof(quad4));
7140             hr = IDirect3DVertexBuffer9_Unlock(vb);
7141             ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7142             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7143             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7144             hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7145             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7146             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7147             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7148                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7149             f_ok = SUCCEEDED(hr);
7150         }
7151
7152         hr = IDirect3DDevice9_EndScene(device);
7153         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7154     }
7155
7156     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7157     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7158     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7159     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160
7161     if(dcl_short) {
7162         color = getPixelColor(device, 480, 360);
7163         ok(color == 0x000000ff || !s_ok,
7164            "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7165     }
7166     if(dcl_ubyte) {
7167         color = getPixelColor(device, 160, 120);
7168         ok(color == 0x0000ffff || !ub_ok,
7169            "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7170     }
7171     if(dcl_color) {
7172         color = getPixelColor(device, 160, 360);
7173         ok(color == 0x00ffff00,
7174            "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7175     }
7176     if(dcl_float) {
7177         color = getPixelColor(device, 480, 120);
7178         ok(color == 0x00ff0000 || !f_ok,
7179            "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7180     }
7181     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7182
7183     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7184     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7185
7186     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
7187     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7188     memcpy(data, quad_transformed, sizeof(quad_transformed));
7189     hr = IDirect3DVertexBuffer9_Unlock(vb);
7190     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7191
7192     hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7193     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7194
7195     hr = IDirect3DDevice9_BeginScene(device);
7196     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7197     if(SUCCEEDED(hr)) {
7198         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7199         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7200         hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7201         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7202
7203         hr = IDirect3DDevice9_EndScene(device);
7204         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7205     }
7206
7207     color = getPixelColor(device, 88, 108);
7208     ok(color == 0x000000ff,
7209        "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7210     color = getPixelColor(device, 92, 108);
7211     ok(color == 0x000000ff,
7212        "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7213     color = getPixelColor(device, 88, 112);
7214     ok(color == 0x000000ff,
7215        "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7216     color = getPixelColor(device, 92, 112);
7217     ok(color == 0x00ffff00,
7218        "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7219
7220     color = getPixelColor(device, 568, 108);
7221     ok(color == 0x000000ff,
7222        "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7223     color = getPixelColor(device, 572, 108);
7224     ok(color == 0x000000ff,
7225        "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7226     color = getPixelColor(device, 568, 112);
7227     ok(color == 0x00ffff00,
7228        "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7229     color = getPixelColor(device, 572, 112);
7230     ok(color == 0x000000ff,
7231        "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7232
7233     color = getPixelColor(device, 88, 298);
7234     ok(color == 0x000000ff,
7235        "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7236     color = getPixelColor(device, 92, 298);
7237     ok(color == 0x00ffff00,
7238        "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7239     color = getPixelColor(device, 88, 302);
7240     ok(color == 0x000000ff,
7241        "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7242     color = getPixelColor(device, 92, 302);
7243     ok(color == 0x000000ff,
7244        "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7245
7246     color = getPixelColor(device, 568, 298);
7247     ok(color == 0x00ffff00,
7248        "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7249     color = getPixelColor(device, 572, 298);
7250     ok(color == 0x000000ff,
7251        "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7252     color = getPixelColor(device, 568, 302);
7253     ok(color == 0x000000ff,
7254        "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7255     color = getPixelColor(device, 572, 302);
7256     ok(color == 0x000000ff,
7257        "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7258
7259     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7260
7261     /* This test is pointless without those two declarations: */
7262     if((!dcl_color_2) || (!dcl_ubyte_2)) {
7263         skip("color-ubyte switching test declarations aren't supported\n");
7264         goto out;
7265     }
7266
7267     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
7268     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7269     memcpy(data, quads, sizeof(quads));
7270     hr = IDirect3DVertexBuffer9_Unlock(vb);
7271     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7272     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7273                                              0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7274     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7275     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
7276     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7277     memcpy(data, colors, sizeof(colors));
7278     hr = IDirect3DVertexBuffer9_Unlock(vb2);
7279     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7280
7281     for(i = 0; i < 2; i++) {
7282         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7283         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7284
7285         hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7286         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7287         if(i == 0) {
7288             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7289         } else {
7290             hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7291         }
7292         ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7293
7294         hr = IDirect3DDevice9_BeginScene(device);
7295         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7296         ub_ok = FALSE;
7297         if(SUCCEEDED(hr)) {
7298             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7299             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7300             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7301             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7302                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7303             ub_ok = SUCCEEDED(hr);
7304
7305             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7306             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7307             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7308             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7309
7310             hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7311             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7312             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7313             ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7314                "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7315             ub_ok = (SUCCEEDED(hr) && ub_ok);
7316
7317             hr = IDirect3DDevice9_EndScene(device);
7318             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7319         }
7320
7321         if(i == 0) {
7322             color = getPixelColor(device, 480, 360);
7323             ok(color == 0x00ff0000,
7324                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7325             color = getPixelColor(device, 160, 120);
7326             ok(color == 0x00ffffff,
7327                 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7328             color = getPixelColor(device, 160, 360);
7329             ok(color == 0x000000ff || !ub_ok,
7330                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7331             color = getPixelColor(device, 480, 120);
7332             ok(color == 0x000000ff || !ub_ok,
7333                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7334         } else {
7335             color = getPixelColor(device, 480, 360);
7336             ok(color == 0x000000ff,
7337                "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7338             color = getPixelColor(device, 160, 120);
7339             ok(color == 0x00ffffff,
7340                "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7341             color = getPixelColor(device, 160, 360);
7342             ok(color == 0x00ff0000 || !ub_ok,
7343                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7344             color = getPixelColor(device, 480, 120);
7345             ok(color == 0x00ff0000 || !ub_ok,
7346                "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7347         }
7348         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7349     }
7350
7351     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7352     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7353     hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7354     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7355     IDirect3DVertexBuffer9_Release(vb2);
7356
7357     out:
7358     IDirect3DVertexBuffer9_Release(vb);
7359     if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7360     if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7361     if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7362     if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7363     if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7364     if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7365     if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7366 }
7367
7368 struct vertex_float16color {
7369     float x, y, z;
7370     DWORD c1, c2;
7371 };
7372
7373 static void test_vshader_float16(IDirect3DDevice9 *device)
7374 {
7375     HRESULT hr;
7376     DWORD color;
7377     void *data;
7378     static const D3DVERTEXELEMENT9 decl_elements[] = {
7379         {0,   0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,       0},
7380         {0,  12,  D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,          0},
7381         D3DDECL_END()
7382     };
7383     IDirect3DVertexDeclaration9 *vdecl = NULL;
7384     IDirect3DVertexBuffer9 *buffer = NULL;
7385     IDirect3DVertexShader9 *shader;
7386     DWORD shader_code[] = {
7387         0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7388         0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7389         0x90e40001, 0x0000ffff
7390     };
7391     struct vertex_float16color quad[] = {
7392         { -1.0,   -1.0,     0.1,        0x3c000000, 0x00000000 }, /* green */
7393         { -1.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7394         {  0.0,   -1.0,     0.1,        0x3c000000, 0x00000000 },
7395         {  0.0,    0.0,     0.1,        0x3c000000, 0x00000000 },
7396
7397         {  0.0,   -1.0,     0.1,        0x00003c00, 0x00000000 }, /* red */
7398         {  0.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7399         {  1.0,   -1.0,     0.1,        0x00003c00, 0x00000000 },
7400         {  1.0,    0.0,     0.1,        0x00003c00, 0x00000000 },
7401
7402         {  0.0,    0.0,     0.1,        0x00000000, 0x00003c00 }, /* blue */
7403         {  0.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7404         {  1.0,    0.0,     0.1,        0x00000000, 0x00003c00 },
7405         {  1.0,    1.0,     0.1,        0x00000000, 0x00003c00 },
7406
7407         { -1.0,    0.0,     0.1,        0x00000000, 0x3c000000 }, /* alpha */
7408         { -1.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7409         {  0.0,    0.0,     0.1,        0x00000000, 0x3c000000 },
7410         {  0.0,    1.0,     0.1,        0x00000000, 0x3c000000 },
7411     };
7412
7413     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7414     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7415
7416     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7417     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7418     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7419     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7420     hr = IDirect3DDevice9_SetVertexShader(device, shader);
7421     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7422
7423     hr = IDirect3DDevice9_BeginScene(device);
7424     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7425     if(SUCCEEDED(hr)) {
7426         hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7427         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7428         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  0, sizeof(quad[0]));
7429         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7430         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  4, sizeof(quad[0]));
7431         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7432         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad +  8, sizeof(quad[0]));
7433         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7434         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7435         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7436
7437         hr = IDirect3DDevice9_EndScene(device);
7438         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7439     }
7440     color = getPixelColor(device, 480, 360);
7441     ok(color == 0x00ff0000,
7442        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7443     color = getPixelColor(device, 160, 120);
7444     ok(color == 0x00000000,
7445        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7446     color = getPixelColor(device, 160, 360);
7447     ok(color == 0x0000ff00,
7448        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7449     color = getPixelColor(device, 480, 120);
7450     ok(color == 0x000000ff,
7451        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7452     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7453
7454     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7455     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7456
7457     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7458                                              D3DPOOL_MANAGED, &buffer, NULL);
7459     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7460     hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
7461     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7462     memcpy(data, quad, sizeof(quad));
7463     hr = IDirect3DVertexBuffer9_Unlock(buffer);
7464     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7465     hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7466     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7467
7468     hr = IDirect3DDevice9_BeginScene(device);
7469     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7470     if(SUCCEEDED(hr)) {
7471             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  0, 2);
7472             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7473             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  4, 2);
7474             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7475             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,  8, 2);
7476             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7477             hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7478             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7479
7480             hr = IDirect3DDevice9_EndScene(device);
7481             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7482     }
7483
7484     color = getPixelColor(device, 480, 360);
7485     ok(color == 0x00ff0000,
7486        "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7487     color = getPixelColor(device, 160, 120);
7488     ok(color == 0x00000000,
7489        "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7490     color = getPixelColor(device, 160, 360);
7491     ok(color == 0x0000ff00,
7492        "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7493     color = getPixelColor(device, 480, 120);
7494     ok(color == 0x000000ff,
7495        "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7496     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7497
7498     hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7499     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7500     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7501     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7502     IDirect3DDevice9_SetVertexShader(device, NULL);
7503     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7504
7505     IDirect3DVertexDeclaration9_Release(vdecl);
7506     IDirect3DVertexShader9_Release(shader);
7507     IDirect3DVertexBuffer9_Release(buffer);
7508 }
7509
7510 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7511 {
7512     D3DCAPS9 caps;
7513     IDirect3DTexture9 *texture;
7514     HRESULT hr;
7515     D3DLOCKED_RECT rect;
7516     unsigned int x, y;
7517     DWORD *dst, color;
7518     const float quad[] = {
7519         -1.0,   -1.0,   0.1,   -0.2,   -0.2,
7520          1.0,   -1.0,   0.1,    1.2,   -0.2,
7521         -1.0,    1.0,   0.1,   -0.2,    1.2,
7522          1.0,    1.0,   0.1,    1.2,    1.2
7523     };
7524     memset(&caps, 0, sizeof(caps));
7525
7526     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7527     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7528     if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7529         /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7530         ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7531            "Card has conditional NP2 support without power of two restriction set\n");
7532         skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7533         return;
7534     } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7535         skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7536         return;
7537     }
7538
7539     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7540     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7541
7542     hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7543     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7544
7545     memset(&rect, 0, sizeof(rect));
7546     hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7547     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7548     for(y = 0; y < 10; y++) {
7549         for(x = 0; x < 10; x++) {
7550             dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7551             if(x == 0 || x == 9 || y == 0 || y == 9) {
7552                 *dst = 0x00ff0000;
7553             } else {
7554                 *dst = 0x000000ff;
7555             }
7556         }
7557     }
7558     hr = IDirect3DTexture9_UnlockRect(texture, 0);
7559     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7560
7561     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7562     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7563     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7564     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7565     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7566     ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7567     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7568     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7569
7570     hr = IDirect3DDevice9_BeginScene(device);
7571     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7572     if(SUCCEEDED(hr)) {
7573         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7574         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7575
7576         hr = IDirect3DDevice9_EndScene(device);
7577         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7578     }
7579
7580     color = getPixelColor(device,    1,  1);
7581     ok(color == 0x00ff0000, "NP2: Pixel   1,  1 has color %08x, expected 0x00ff0000\n", color);
7582     color = getPixelColor(device, 639, 479);
7583     ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7584
7585     color = getPixelColor(device, 135, 101);
7586     ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7587     color = getPixelColor(device, 140, 101);
7588     ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7589     color = getPixelColor(device, 135, 105);
7590     ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7591     color = getPixelColor(device, 140, 105);
7592     ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7593
7594     color = getPixelColor(device, 135, 376);
7595     ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7596     color = getPixelColor(device, 140, 376);
7597     ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7598     color = getPixelColor(device, 135, 379);
7599     ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7600     color = getPixelColor(device, 140, 379);
7601     ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7602
7603     color = getPixelColor(device, 500, 101);
7604     ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7605     color = getPixelColor(device, 504, 101);
7606     ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7607     color = getPixelColor(device, 500, 105);
7608     ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7609     color = getPixelColor(device, 504, 105);
7610     ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7611
7612     color = getPixelColor(device, 500, 376);
7613     ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7614     color = getPixelColor(device, 504, 376);
7615     ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7616     color = getPixelColor(device, 500, 380);
7617     ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7618     color = getPixelColor(device, 504, 380);
7619     ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7620
7621     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7622
7623     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7624     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7625     IDirect3DTexture9_Release(texture);
7626 }
7627
7628 static void vFace_register_test(IDirect3DDevice9 *device)
7629 {
7630     HRESULT hr;
7631     DWORD color;
7632     const DWORD shader_code[] = {
7633         0xffff0300,                                                             /* ps_3_0                     */
7634         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7635         0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7636         0x0200001f, 0x80000000, 0x900f1001,                                     /* dcl vFace                  */
7637         0x02000001, 0x800f0001, 0xa0e40001,                                     /* mov r1, c1                 */
7638         0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001,             /* cmp r0, vFace, c0, r1      */
7639         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
7640         0x0000ffff                                                              /* END                        */
7641     };
7642     const DWORD vshader_code[] = {
7643         0xfffe0300,                                                             /* vs_3_0               */
7644         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
7645         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
7646         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
7647         0x0000ffff                                                              /* end                  */
7648     };
7649     IDirect3DPixelShader9 *shader;
7650     IDirect3DVertexShader9 *vshader;
7651     IDirect3DTexture9 *texture;
7652     IDirect3DSurface9 *surface, *backbuffer;
7653     const float quad[] = {
7654         -1.0,   -1.0,   0.1,
7655          1.0,   -1.0,   0.1,
7656         -1.0,    0.0,   0.1,
7657
7658          1.0,   -1.0,   0.1,
7659          1.0,    0.0,   0.1,
7660         -1.0,    0.0,   0.1,
7661
7662         -1.0,    0.0,   0.1,
7663         -1.0,    1.0,   0.1,
7664          1.0,    0.0,   0.1,
7665
7666          1.0,    0.0,   0.1,
7667         -1.0,    1.0,   0.1,
7668          1.0,    1.0,   0.1,
7669     };
7670     const float blit[] = {
7671          0.0,   -1.0,   0.1,    0.0,    0.0,
7672          1.0,   -1.0,   0.1,    1.0,    0.0,
7673          0.0,    1.0,   0.1,    0.0,    1.0,
7674          1.0,    1.0,   0.1,    1.0,    1.0,
7675     };
7676
7677     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7678     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7679     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7680     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7681     hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7682     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7683     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7684     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7685     hr = IDirect3DDevice9_SetPixelShader(device, shader);
7686     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7687     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7688     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7689     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7690     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7691     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7692     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7693
7694     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7695     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7696
7697     hr = IDirect3DDevice9_BeginScene(device);
7698     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7699     if(SUCCEEDED(hr)) {
7700         /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7701         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7702         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7703         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7704         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7705         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7706         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7707         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7708         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7709         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7710         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7711
7712         /* Blit the texture onto the back buffer to make it visible */
7713         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7714         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
7715         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7716         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7717         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7718         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7719         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7720         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7721         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7722         ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7723         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7724         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7725
7726         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7727         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7728
7729         hr = IDirect3DDevice9_EndScene(device);
7730         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7731     }
7732
7733     color = getPixelColor(device, 160, 360);
7734     ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7735     color = getPixelColor(device, 160, 120);
7736     ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7737     color = getPixelColor(device, 480, 360);
7738     ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7739     color = getPixelColor(device, 480, 120);
7740     ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7741     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7742
7743     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7744     IDirect3DDevice9_SetTexture(device, 0, NULL);
7745     IDirect3DPixelShader9_Release(shader);
7746     IDirect3DVertexShader9_Release(vshader);
7747     IDirect3DSurface9_Release(surface);
7748     IDirect3DSurface9_Release(backbuffer);
7749     IDirect3DTexture9_Release(texture);
7750 }
7751
7752 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7753 {
7754     HRESULT hr;
7755     DWORD color;
7756     int i;
7757     D3DCAPS9 caps;
7758     BOOL L6V5U5_supported = FALSE;
7759     IDirect3DTexture9 *tex1, *tex2;
7760     D3DLOCKED_RECT locked_rect;
7761
7762     static const float quad[][7] = {
7763         {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7764         {-128.0f/640.0f,  128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7765         { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7766         { 128.0f/640.0f,  128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7767     };
7768
7769     static const D3DVERTEXELEMENT9 decl_elements[] = {
7770         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7771         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7772         {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7773         D3DDECL_END()
7774     };
7775
7776     /* use asymmetric matrix to test loading */
7777     float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7778     float scale, offset;
7779
7780     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7781     IDirect3DTexture9           *texture            = NULL;
7782
7783     memset(&caps, 0, sizeof(caps));
7784     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7785     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7786     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7787         skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7788         return;
7789     } else {
7790         /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7791          * They report that it is not supported, but after that bump mapping works properly. So just test
7792          * if the format is generally supported, and check the BUMPENVMAP flag
7793          */
7794         IDirect3D9 *d3d9;
7795
7796         IDirect3DDevice9_GetDirect3D(device, &d3d9);
7797         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7798                                           D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7799         L6V5U5_supported = SUCCEEDED(hr);
7800         hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7801                                           D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7802         IDirect3D9_Release(d3d9);
7803         if(FAILED(hr)) {
7804             skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7805             return;
7806         }
7807     }
7808
7809     /* Generate the textures */
7810     generate_bumpmap_textures(device);
7811
7812     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7813     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7814     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7815     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7816     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7817     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7818     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7819     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7820
7821     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7822     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7823     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7824     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7825     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7826     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7827
7828     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7829     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7830     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7831     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7832     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7833     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7834
7835     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7836     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7837
7838     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7839     ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7840
7841     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7842     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7843
7844
7845     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7846     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7847     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7848     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7849
7850     hr = IDirect3DDevice9_BeginScene(device);
7851     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7852
7853     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7854     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7855
7856     hr = IDirect3DDevice9_EndScene(device);
7857     ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7858
7859     /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7860      * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7861      * But since testing the color match is not the purpose of the test don't be too picky
7862      */
7863     color = getPixelColor(device, 320-32, 240);
7864     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7865     color = getPixelColor(device, 320+32, 240);
7866     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7867     color = getPixelColor(device, 320, 240-32);
7868     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7869     color = getPixelColor(device, 320, 240+32);
7870     ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7871     color = getPixelColor(device, 320, 240);
7872     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7873     color = getPixelColor(device, 320+32, 240+32);
7874     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7875     color = getPixelColor(device, 320-32, 240+32);
7876     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7877     color = getPixelColor(device, 320+32, 240-32);
7878     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7879     color = getPixelColor(device, 320-32, 240-32);
7880     ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7881     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7882     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7883
7884     for(i = 0; i < 2; i++) {
7885         hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7886         ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7887         IDirect3DTexture9_Release(texture); /* For the GetTexture */
7888         hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7889         ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7890         IDirect3DTexture9_Release(texture); /* To destroy it */
7891     }
7892
7893     if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7894         skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7895         goto cleanup;
7896     }
7897     if(L6V5U5_supported == FALSE) {
7898         skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7899         goto cleanup;
7900     }
7901
7902     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7903     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7904     /* This test only tests the luminance part. The bumpmapping part was already tested above and
7905      * would only make this test more complicated
7906      */
7907     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7908     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7909     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7910     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7911
7912     memset(&locked_rect, 0, sizeof(locked_rect));
7913     hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7914     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7915     *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7916     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7917     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7918
7919     memset(&locked_rect, 0, sizeof(locked_rect));
7920     hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7921     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7922     *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7923     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7924     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7925
7926     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7927     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7928     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7929     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7930
7931     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7932     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7933     scale = 2.0;
7934     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7935     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7936     offset = 0.1;
7937     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7938     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7939
7940     hr = IDirect3DDevice9_BeginScene(device);
7941     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7942     if(SUCCEEDED(hr)) {
7943         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7944         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7945         hr = IDirect3DDevice9_EndScene(device);
7946         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7947     }
7948
7949     color = getPixelColor(device, 320, 240);
7950     /* red:   1.0  * (0.25 * 2.0 + 0.1) = 1.0  * 0.6 = 0.6  = 0x99
7951      * green: 0.5  * (0.25 * 2.0 + 0.1) = 0.5  * 0.6 = 0.3  = 0x4c
7952      * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7953      */
7954     ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7955     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7957
7958     /* Check a result scale factor > 1.0 */
7959     scale = 10;
7960     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7961     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7962     offset = 10;
7963     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7964     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7965
7966     hr = IDirect3DDevice9_BeginScene(device);
7967     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7968     if(SUCCEEDED(hr)) {
7969         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7970         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7971         hr = IDirect3DDevice9_EndScene(device);
7972         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7973     }
7974     color = getPixelColor(device, 320, 240);
7975     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7976     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7977     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7978
7979     /* Check clamping in the scale factor calculation */
7980     scale = 1000;
7981     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7982     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7983     offset = -1;
7984     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7985     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7986
7987     hr = IDirect3DDevice9_BeginScene(device);
7988     ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7989     if(SUCCEEDED(hr)) {
7990         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7991         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7992         hr = IDirect3DDevice9_EndScene(device);
7993         ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7994     }
7995     color = getPixelColor(device, 320, 240);
7996     ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7997     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7998     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7999
8000     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8001     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8002     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8003     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
8004
8005     IDirect3DTexture9_Release(tex1);
8006     IDirect3DTexture9_Release(tex2);
8007
8008 cleanup:
8009     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8010     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8011     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
8012     ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
8013
8014     hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8015     ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8016     IDirect3DVertexDeclaration9_Release(vertex_declaration);
8017 }
8018
8019 static void stencil_cull_test(IDirect3DDevice9 *device) {
8020     HRESULT hr;
8021     IDirect3DSurface9 *depthstencil = NULL;
8022     D3DSURFACE_DESC desc;
8023     float quad1[] = {
8024         -1.0,   -1.0,   0.1,
8025          0.0,   -1.0,   0.1,
8026         -1.0,    0.0,   0.1,
8027          0.0,    0.0,   0.1,
8028     };
8029     float quad2[] = {
8030          0.0,   -1.0,   0.1,
8031          1.0,   -1.0,   0.1,
8032          0.0,    0.0,   0.1,
8033          1.0,    0.0,   0.1,
8034     };
8035     float quad3[] = {
8036         0.0,    0.0,   0.1,
8037         1.0,    0.0,   0.1,
8038         0.0,    1.0,   0.1,
8039         1.0,    1.0,   0.1,
8040     };
8041     float quad4[] = {
8042         -1.0,    0.0,   0.1,
8043          0.0,    0.0,   0.1,
8044         -1.0,    1.0,   0.1,
8045          0.0,    1.0,   0.1,
8046     };
8047     struct vertex painter[] = {
8048        {-1.0,   -1.0,   0.0,    0x00000000},
8049        { 1.0,   -1.0,   0.0,    0x00000000},
8050        {-1.0,    1.0,   0.0,    0x00000000},
8051        { 1.0,    1.0,   0.0,    0x00000000},
8052     };
8053     WORD indices_cw[]  = {0, 1, 3};
8054     WORD indices_ccw[] = {0, 2, 3};
8055     unsigned int i;
8056     DWORD color;
8057
8058     IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8059     if(depthstencil == NULL) {
8060         skip("No depth stencil buffer\n");
8061         return;
8062     }
8063     hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8064     ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8065     IDirect3DSurface9_Release(depthstencil);
8066     if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8067         skip("No 4 or 8 bit stencil surface\n");
8068         return;
8069     }
8070
8071     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8072     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8073     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8074
8075     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8076     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8078     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8079     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8080     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8081     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8082     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8083
8084     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8085     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8086     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8087     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8088     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8089     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8090
8091     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8092     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8093     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8094     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8095
8096     /* First pass: Fill the stencil buffer with some values... */
8097     hr = IDirect3DDevice9_BeginScene(device);
8098     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8099     if(SUCCEEDED(hr))
8100     {
8101         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8102         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8104                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8105         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8106         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8107                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8108         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8109
8110         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8111         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8112         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8113         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8114         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8115                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8116         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8117         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8118                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8119         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8120
8121         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8122         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8123         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8124                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8125         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8126         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8127                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8128         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8129
8130         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8131         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8132         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8133                 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8134         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8135         hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8136                 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8137         ok(SUCCEEDED(hr), "IDirect3DDevice9_DrawIndexedPrimitiveUP returned %#x.\n", hr);
8138
8139         hr = IDirect3DDevice9_EndScene(device);
8140         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8141     }
8142
8143     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8144     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8145     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8146     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8147     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8148     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8149     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8150     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8151     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8152     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8153     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8154     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8155     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8156
8157     /* 2nd pass: Make the stencil values visible */
8158     hr = IDirect3DDevice9_BeginScene(device);
8159     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8160     if(SUCCEEDED(hr))
8161     {
8162         IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8163         for(i = 0; i < 16; i++) {
8164             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8165             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8166
8167             painter[0].diffuse = (i * 16); /* Creates shades of blue */
8168             painter[1].diffuse = (i * 16);
8169             painter[2].diffuse = (i * 16);
8170             painter[3].diffuse = (i * 16);
8171             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8172             ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8173         }
8174         hr = IDirect3DDevice9_EndScene(device);
8175         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8176     }
8177
8178     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8179     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8180
8181     color = getPixelColor(device, 160, 420);
8182     ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8183     color = getPixelColor(device, 160, 300);
8184     ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8185
8186     color = getPixelColor(device, 480, 420);
8187     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8188     color = getPixelColor(device, 480, 300);
8189     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8190
8191     color = getPixelColor(device, 160, 180);
8192     ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8193     color = getPixelColor(device, 160, 60);
8194     ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8195
8196     color = getPixelColor(device, 480, 180);
8197     ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8198     color = getPixelColor(device, 480, 60);
8199     ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8200
8201     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8202     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8203 }
8204
8205 static void vpos_register_test(IDirect3DDevice9 *device)
8206 {
8207     HRESULT hr;
8208     DWORD color;
8209     const DWORD shader_code[] = {
8210     0xffff0300,                                                             /* ps_3_0                     */
8211     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8212     0x03000002, 0x80030000, 0x90541000, 0xa1fe0000,                         /* sub r0.xy, vPos.xy, c0.zw  */
8213     0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                 */
8214     0x02000001, 0x80080002, 0xa0550000,                                     /* mov r2.a, c0.y             */
8215     0x02000001, 0x80010002, 0xa0550000,                                     /* mov r2.r, c0.y             */
8216     0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001,             /* cmp r2.g, r0.x, r1.x, r1.y */
8217     0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001,             /* cmp r2.b, r0.y, r1.x, r1.y */
8218     0x02000001, 0x800f0800, 0x80e40002,                                     /* mov oC0, r2                */
8219     0x0000ffff                                                              /* end                        */
8220     };
8221     const DWORD shader_frac_code[] = {
8222     0xffff0300,                                                             /* ps_3_0                     */
8223     0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8224     0x0200001f, 0x80000000, 0x90031000,                                     /* dcl vPos.xy                */
8225     0x02000001, 0x800f0000, 0xa0e40000,                                     /* mov r0, c0                 */
8226     0x02000013, 0x80030000, 0x90541000,                                     /* frc r0.xy, vPos.xy         */
8227     0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                */
8228     0x0000ffff                                                              /* end                        */
8229     };
8230     const DWORD vshader_code[] = {
8231         0xfffe0300,                                                             /* vs_3_0               */
8232         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0      */
8233         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0      */
8234         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0           */
8235         0x0000ffff                                                              /* end                  */
8236     };
8237     IDirect3DVertexShader9 *vshader;
8238     IDirect3DPixelShader9 *shader, *shader_frac;
8239     IDirect3DSurface9 *surface = NULL, *backbuffer;
8240     const float quad[] = {
8241         -1.0,   -1.0,   0.1,    0.0,    0.0,
8242          1.0,   -1.0,   0.1,    1.0,    0.0,
8243         -1.0,    1.0,   0.1,    0.0,    1.0,
8244          1.0,    1.0,   0.1,    1.0,    1.0,
8245     };
8246     D3DLOCKED_RECT lr;
8247     float constant[4] = {1.0, 0.0, 320, 240};
8248     DWORD *pos;
8249
8250     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8251     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8252     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8253     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
8254     hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8255     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8256     hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8257     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8258     hr = IDirect3DDevice9_SetPixelShader(device, shader);
8259     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8260     hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8261     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8262     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8263     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8264     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8265     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8266
8267     hr = IDirect3DDevice9_BeginScene(device);
8268     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8269     if(SUCCEEDED(hr)) {
8270         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8271         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8272         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8273         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8274         hr = IDirect3DDevice9_EndScene(device);
8275         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8276     }
8277
8278     /* This has to be pixel exact */
8279     color = getPixelColor(device, 319, 239);
8280     ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8281     color = getPixelColor(device, 320, 239);
8282     ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8283     color = getPixelColor(device, 319, 240);
8284     ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8285     color = getPixelColor(device, 320, 240);
8286     ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8287     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8288
8289     hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8290                                              &surface, NULL);
8291     ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8292     hr = IDirect3DDevice9_BeginScene(device);
8293     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8294     if(SUCCEEDED(hr)) {
8295         constant[2] = 16; constant[3] = 16;
8296         hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8297         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8298         hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8299         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8300         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8301         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8302         hr = IDirect3DDevice9_EndScene(device);
8303         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8304     }
8305     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8306     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8307
8308     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8309     color = *pos & 0x00ffffff;
8310     ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8311     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8312     color = *pos & 0x00ffffff;
8313     ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8314     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8315     color = *pos & 0x00ffffff;
8316     ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8317     pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8318     color = *pos & 0x00ffffff;
8319     ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8320
8321     hr = IDirect3DSurface9_UnlockRect(surface);
8322     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8323
8324     /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8325      * have full control over the multisampling setting inside this test
8326      */
8327     hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8328     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8329     hr = IDirect3DDevice9_BeginScene(device);
8330     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8331     if(SUCCEEDED(hr)) {
8332         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8333         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8334         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8335         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8336         hr = IDirect3DDevice9_EndScene(device);
8337         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8338     }
8339     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8340     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8341
8342     hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8343     ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8344
8345     pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8346     color = *pos & 0x00ffffff;
8347     ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8348
8349     hr = IDirect3DSurface9_UnlockRect(surface);
8350     ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8351
8352     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8353     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8354     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8355     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
8356     IDirect3DPixelShader9_Release(shader);
8357     IDirect3DPixelShader9_Release(shader_frac);
8358     IDirect3DVertexShader9_Release(vshader);
8359     if(surface) IDirect3DSurface9_Release(surface);
8360     IDirect3DSurface9_Release(backbuffer);
8361 }
8362
8363 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
8364 {
8365     D3DCOLOR color;
8366
8367     color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
8368     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8369     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8370     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8371     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8372
8373     ++r;
8374     color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
8375     if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
8376     if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
8377     if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
8378     if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
8379
8380     return TRUE;
8381 }
8382
8383 static void pointsize_test(IDirect3DDevice9 *device)
8384 {
8385     HRESULT hr;
8386     D3DCAPS9 caps;
8387     D3DMATRIX matrix;
8388     D3DMATRIX identity;
8389     float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8390     DWORD color;
8391     IDirect3DSurface9 *rt, *backbuffer;
8392     IDirect3DTexture9 *tex1, *tex2;
8393     RECT rect = {0, 0, 128, 128};
8394     D3DLOCKED_RECT lr;
8395     const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000,
8396                                 0x00000000, 0x00000000};
8397     const DWORD tex2_data[4] = {0x00000000, 0x0000ff00,
8398                                 0x00000000, 0x0000ff00};
8399
8400     const float vertices[] = {
8401         64,     64,     0.1,
8402         128,    64,     0.1,
8403         192,    64,     0.1,
8404         256,    64,     0.1,
8405         320,    64,     0.1,
8406         384,    64,     0.1,
8407         448,    64,     0.1,
8408         512,    64,     0.1,
8409     };
8410
8411     /* 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 */
8412     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;
8413     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;
8414     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;
8415     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;
8416
8417     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;
8418     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;
8419     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;
8420     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;
8421
8422     memset(&caps, 0, sizeof(caps));
8423     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8424     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8425     if(caps.MaxPointSize < 32.0) {
8426         skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8427         return;
8428     }
8429
8430     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8431     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8432     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8433     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8434     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8435     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8436     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8437     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8438
8439     hr = IDirect3DDevice9_BeginScene(device);
8440     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8441     if (SUCCEEDED(hr))
8442     {
8443         ptsize = 15.0;
8444         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8445         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8446         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8447         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8448
8449         ptsize = 31.0;
8450         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8451         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8452         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8453         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8454
8455         ptsize = 30.75;
8456         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8457         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8458         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8459         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8460
8461         if (caps.MaxPointSize >= 63.0)
8462         {
8463             ptsize = 63.0;
8464             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8465             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8466             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8467             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8468
8469             ptsize = 62.75;
8470             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8471             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8472             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8473             ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8474         }
8475
8476         ptsize = 1.0;
8477         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8478         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8479         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8480         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8481
8482         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8483         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8484         hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *) (&ptsizemin_orig));
8485         ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8486
8487         /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8488         ptsize = 15.0;
8489         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8490         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8491         ptsize = 1.0;
8492         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8493         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8494         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8495         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8496
8497         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8498         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8499
8500         /* pointsize < pointsize_min < pointsize_max?
8501          * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
8502         ptsize = 1.0;
8503         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8504         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8505         ptsize = 15.0;
8506         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8507         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8508         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8509         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8510
8511         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8512         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8513
8514         hr = IDirect3DDevice9_EndScene(device);
8515         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8516     }
8517
8518     ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
8519     ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
8520     ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
8521
8522     if (caps.MaxPointSize >= 63.0)
8523     {
8524         ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
8525         ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
8526     }
8527
8528     ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
8529     /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
8530     ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
8531     /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
8532     ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
8533
8534     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8535
8536     /* The following code tests point sprites with two textures, to see if each texture coordinate unit
8537      * generates texture coordinates for the point(result: Yes, it does)
8538      *
8539      * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
8540      * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
8541      * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
8542      */
8543     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8544     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8545
8546     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
8547     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8548     hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
8549     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
8550     memset(&lr, 0, sizeof(lr));
8551     hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
8552     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8553     memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
8554     hr = IDirect3DTexture9_UnlockRect(tex1, 0);
8555     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8556     memset(&lr, 0, sizeof(lr));
8557     hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
8558     ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
8559     memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
8560     hr = IDirect3DTexture9_UnlockRect(tex2, 0);
8561     ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
8562     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8563     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8564     hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
8565     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8566     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8567     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8568     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8569     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8570     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
8571     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8572     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8573     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8574     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
8575     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8576
8577     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
8578     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8579     ptsize = 32.0;
8580     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8581     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8582
8583     hr = IDirect3DDevice9_BeginScene(device);
8584     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8585     if(SUCCEEDED(hr))
8586     {
8587         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8588         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8589         hr = IDirect3DDevice9_EndScene(device);
8590         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8591     }
8592
8593     color = getPixelColor(device, 64-4, 64-4);
8594     ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
8595     color = getPixelColor(device, 64-4, 64+4);
8596     ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
8597     color = getPixelColor(device, 64+4, 64+4);
8598     ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
8599     color = getPixelColor(device, 64+4, 64-4);
8600     ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
8601     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8602
8603     U(matrix).m[0][0] =  1.0f / 64.0f;
8604     U(matrix).m[1][1] = -1.0f / 64.0f;
8605     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8606     ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
8607
8608     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
8609     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
8610
8611     hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
8612             D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
8613     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
8614
8615     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
8616     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8617     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 0.0f, 0);
8618     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
8619
8620     hr = IDirect3DDevice9_BeginScene(device);
8621     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
8622     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8623     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
8624     hr = IDirect3DDevice9_EndScene(device);
8625     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
8626
8627     hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
8628     ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
8629     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8630     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
8631     IDirect3DSurface9_Release(backbuffer);
8632     IDirect3DSurface9_Release(rt);
8633
8634     color = getPixelColor(device, 64-4, 64-4);
8635     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 0),
8636             "Expected color 0x00ff0000, got 0x%08x.\n", color);
8637     color = getPixelColor(device, 64+4, 64-4);
8638     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 0),
8639             "Expected color 0x00ffff00, got 0x%08x.\n", color);
8640     color = getPixelColor(device, 64-4, 64+4);
8641     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00), 0),
8642             "Expected color 0x00000000, got 0x%08x.\n", color);
8643     color = getPixelColor(device, 64+4, 64+4);
8644     ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
8645             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8646
8647     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8648     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
8649
8650     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8651     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8652     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8653     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
8654     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8655     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8656     hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
8657     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
8658     IDirect3DTexture9_Release(tex1);
8659     IDirect3DTexture9_Release(tex2);
8660
8661     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, FALSE);
8662     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8664     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8665     hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8666     ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8667 }
8668
8669 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8670 {
8671     static const DWORD vshader_code[] =
8672     {
8673         0xfffe0300,                                                             /* vs_3_0                     */
8674         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0            */
8675         0x0200001f, 0x80000000, 0xe00f0000,                                     /* dcl_position o0            */
8676         0x02000001, 0xe00f0000, 0x90e40000,                                     /* mov o0, v0                 */
8677         0x0000ffff                                                              /* end                        */
8678     };
8679     static const DWORD pshader_code[] =
8680     {
8681         0xffff0300,                                                             /* ps_3_0                     */
8682         0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
8683         0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
8684         0x02000001, 0x800f0800, 0xa0e40000,                                     /* mov oC0, c0                */
8685         0x02000001, 0x800f0801, 0xa0e40001,                                     /* mov oC1, c1                */
8686         0x0000ffff                                                              /* end                        */
8687     };
8688
8689     HRESULT hr;
8690     IDirect3DVertexShader9 *vs;
8691     IDirect3DPixelShader9 *ps;
8692     IDirect3DTexture9 *tex1, *tex2;
8693     IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
8694     D3DCAPS9 caps;
8695     DWORD color;
8696     float quad[] = {
8697        -1.0,   -1.0,    0.1,
8698         1.0,   -1.0,    0.1,
8699        -1.0,    1.0,    0.1,
8700         1.0,    1.0,    0.1,
8701     };
8702     float texquad[] = {
8703        -1.0,   -1.0,    0.1,    0.0,    0.0,
8704         0.0,   -1.0,    0.1,    1.0,    0.0,
8705        -1.0,    1.0,    0.1,    0.0,    1.0,
8706         0.0,    1.0,    0.1,    1.0,    1.0,
8707
8708         0.0,   -1.0,    0.1,    0.0,    0.0,
8709         1.0,   -1.0,    0.1,    1.0,    0.0,
8710         0.0,    1.0,    0.1,    0.0,    1.0,
8711         1.0,    1.0,    0.1,    1.0,    1.0,
8712     };
8713
8714     memset(&caps, 0, sizeof(caps));
8715     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8716     ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8717     if(caps.NumSimultaneousRTs < 2) {
8718         skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8719         return;
8720     }
8721
8722     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8723     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8724
8725     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
8726             D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
8727     ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
8728
8729     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8730             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8731     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8732     hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
8733             D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8734     ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8735     hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
8736     ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
8737     hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &ps);
8738     ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8739
8740     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8741     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8742     hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8743     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8744     hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8745     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8746
8747     hr = IDirect3DDevice9_SetVertexShader(device, vs);
8748     ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8749     hr = IDirect3DDevice9_SetPixelShader(device, ps);
8750     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8751     hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8752     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8753     hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8754     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8755     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8756     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8757
8758     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8759     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8760     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8761     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8762     color = getPixelColorFromSurface(readback, 8, 8);
8763     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8764             "Expected color 0x000000ff, got 0x%08x.\n", color);
8765     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8766     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8767     color = getPixelColorFromSurface(readback, 8, 8);
8768     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
8769             "Expected color 0x000000ff, got 0x%08x.\n", color);
8770
8771     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8772     ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
8773     hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
8774     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8775     color = getPixelColorFromSurface(readback, 8, 8);
8776     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8777             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8778     hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
8779     ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
8780     color = getPixelColorFromSurface(readback, 8, 8);
8781     ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
8782             "Expected color 0x0000ff00, got 0x%08x.\n", color);
8783
8784     hr = IDirect3DDevice9_BeginScene(device);
8785     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8786     if(SUCCEEDED(hr)) {
8787         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8788         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8789
8790         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
8791         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
8792         hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8793         ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8794         hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8795         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8796         hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8797         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8798         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8799         ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8800
8801         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8802         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8803         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8804         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8805
8806         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8807         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8808         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8809         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8810
8811         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8812         ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8813
8814         hr = IDirect3DDevice9_EndScene(device);
8815         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8816     }
8817
8818     color = getPixelColor(device, 160, 240);
8819     ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8820     color = getPixelColor(device, 480, 240);
8821     ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8822     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8823
8824     IDirect3DPixelShader9_Release(ps);
8825     IDirect3DVertexShader9_Release(vs);
8826     IDirect3DTexture9_Release(tex1);
8827     IDirect3DTexture9_Release(tex2);
8828     IDirect3DSurface9_Release(surf1);
8829     IDirect3DSurface9_Release(surf2);
8830     IDirect3DSurface9_Release(backbuf);
8831     IDirect3DSurface9_Release(readback);
8832 }
8833
8834 struct formats {
8835     const char *fmtName;
8836     D3DFORMAT textureFormat;
8837     DWORD resultColorBlending;
8838     DWORD resultColorNoBlending;
8839 };
8840
8841 static const struct formats test_formats[] = {
8842   { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8843   { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8844   { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8845   { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8846   { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8847   { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8848   { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8849   { NULL, 0 }
8850 };
8851
8852 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8853 {
8854     HRESULT hr;
8855     IDirect3DTexture9 *offscreenTexture = NULL;
8856     IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8857     IDirect3D9 *d3d = NULL;
8858     DWORD color;
8859     DWORD r0, g0, b0, r1, g1, b1;
8860     int fmt_index;
8861
8862     static const float quad[][5] = {
8863         {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8864         {-0.5f,  0.5f, 0.1f, 0.0f, 1.0f},
8865         { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8866         { 0.5f,  0.5f, 0.1f, 1.0f, 1.0f},
8867     };
8868
8869     /* Quad with R=0x10, G=0x20 */
8870     static const struct vertex quad1[] = {
8871         {-1.0f, -1.0f, 0.1f, 0x80102000},
8872         {-1.0f,  1.0f, 0.1f, 0x80102000},
8873         { 1.0f, -1.0f, 0.1f, 0x80102000},
8874         { 1.0f,  1.0f, 0.1f, 0x80102000},
8875     };
8876
8877     /* Quad with R=0x20, G=0x10 */
8878     static const struct vertex quad2[] = {
8879         {-1.0f, -1.0f, 0.1f, 0x80201000},
8880         {-1.0f,  1.0f, 0.1f, 0x80201000},
8881         { 1.0f, -1.0f, 0.1f, 0x80201000},
8882         { 1.0f,  1.0f, 0.1f, 0x80201000},
8883     };
8884
8885     IDirect3DDevice9_GetDirect3D(device, &d3d);
8886
8887     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8888     ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8889     if(!backbuffer) {
8890         goto out;
8891     }
8892
8893     for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8894     {
8895         D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8896         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8897            skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8898            continue;
8899         }
8900
8901         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8902         ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8903
8904         hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8905         ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8906         if(!offscreenTexture) {
8907             continue;
8908         }
8909
8910         hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8911         ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8912         if(!offscreen) {
8913             continue;
8914         }
8915
8916         hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8917         ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8918
8919         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8920         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8921         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8922         ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8923         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8924         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8925         hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8926         ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8927         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8928         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8929
8930         /* Below we will draw two quads with different colors and try to blend them together.
8931          * The result color is compared with the expected outcome.
8932          */
8933         if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8934             hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8935             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8936             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8937             ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8938
8939             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8940             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8941
8942             /* Draw a quad using color 0x0010200 */
8943             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8944             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8945             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8946             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8947             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8948             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8949
8950             /* Draw a quad using color 0x0020100 */
8951             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8952             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8953             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8954             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8955             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8956             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8957
8958             /* We don't want to blend the result on the backbuffer */
8959             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8960             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8961
8962             /* Prepare rendering the 'blended' texture quad to the backbuffer */
8963             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8964             ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8965             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8966             ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8967
8968             hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8969             ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8970
8971             /* This time with the texture */
8972             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8973             ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8974
8975             IDirect3DDevice9_EndScene(device);
8976         }
8977
8978         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8979             /* Compare the color of the center quad with our expectation */
8980             color = getPixelColor(device, 320, 240);
8981             r0 = (color & 0x00ff0000) >> 16;
8982             g0 = (color & 0x0000ff00) >>  8;
8983             b0 = (color & 0x000000ff) >>  0;
8984
8985             r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8986             g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >>  8;
8987             b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >>  0;
8988
8989             ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8990                g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8991                b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8992                "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8993         } else {
8994             /* No pixel shader blending is supported so expect garbage. The type of 'garbage' depends on the driver version and OS.
8995              * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8996              * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8997             color = getPixelColor(device, 320, 240);
8998             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);
8999         }
9000         IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9001
9002         IDirect3DDevice9_SetTexture(device, 0, NULL);
9003         if(offscreenTexture) {
9004             IDirect3DTexture9_Release(offscreenTexture);
9005         }
9006         if(offscreen) {
9007             IDirect3DSurface9_Release(offscreen);
9008         }
9009     }
9010
9011 out:
9012     /* restore things */
9013     if(backbuffer) {
9014         IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9015         IDirect3DSurface9_Release(backbuffer);
9016     }
9017 }
9018
9019 static void tssargtemp_test(IDirect3DDevice9 *device)
9020 {
9021     HRESULT hr;
9022     DWORD color;
9023     static const struct vertex quad[] = {
9024         {-1.0,     -1.0,    0.1,    0x00ff0000},
9025         { 1.0,     -1.0,    0.1,    0x00ff0000},
9026         {-1.0,      1.0,    0.1,    0x00ff0000},
9027         { 1.0,      1.0,    0.1,    0x00ff0000}
9028     };
9029     D3DCAPS9 caps;
9030
9031     memset(&caps, 0, sizeof(caps));
9032     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9033     ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
9034     if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
9035         skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
9036         return;
9037     }
9038
9039     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9040     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9041
9042     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9043     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9044     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9045     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9046
9047     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9048     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9049     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9050     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9051     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
9052     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9053
9054     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
9055     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9056     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
9057     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9058     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
9059     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9060
9061     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9062     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9063
9064     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
9065     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
9066     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9067     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9068
9069     hr = IDirect3DDevice9_BeginScene(device);
9070     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
9071     if(SUCCEEDED(hr)) {
9072         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9073         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
9074         hr = IDirect3DDevice9_EndScene(device);
9075         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
9076     }
9077     color = getPixelColor(device, 320, 240);
9078     ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
9079     IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9080
9081     /* Set stage 1 back to default */
9082     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
9083     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9084     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9085     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9086     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9087     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9088     hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9089     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9090     hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
9091     ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
9092 }
9093
9094 struct testdata
9095 {
9096     DWORD idxVertex; /* number of instances in the first stream */
9097     DWORD idxColor; /* number of instances in the second stream */
9098     DWORD idxInstance; /* should be 1 ?? */
9099     DWORD color1; /* color 1 instance */
9100     DWORD color2; /* color 2 instance */
9101     DWORD color3; /* color 3 instance */
9102     DWORD color4; /* color 4 instance */
9103     WORD strVertex; /* specify which stream to use 0-2*/
9104     WORD strColor;
9105     WORD strInstance;
9106 };
9107
9108 static const struct testdata testcases[]=
9109 {
9110     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  0 */
9111     {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  1 */
9112     {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  2 */
9113     {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  3 */
9114     {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /*  4 */
9115     {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  5 */
9116     {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  6 */
9117     {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  7 */
9118     {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /*  8 */
9119     {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /*  9 */
9120     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
9121     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
9122     {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
9123     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
9124     {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
9125 /*
9126     This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1))  has to return D3DERR_INVALIDCALL!
9127     {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
9128 */
9129 };
9130
9131 /* Drawing Indexed Geometry with instances*/
9132 static void stream_test(IDirect3DDevice9 *device)
9133 {
9134     IDirect3DVertexBuffer9 *vb = NULL;
9135     IDirect3DVertexBuffer9 *vb2 = NULL;
9136     IDirect3DVertexBuffer9 *vb3 = NULL;
9137     IDirect3DIndexBuffer9 *ib = NULL;
9138     IDirect3DVertexDeclaration9 *pDecl = NULL;
9139     IDirect3DVertexShader9 *shader = NULL;
9140     HRESULT hr;
9141     BYTE *data;
9142     DWORD color;
9143     DWORD ind;
9144     unsigned i;
9145
9146     const DWORD shader_code[] =
9147     {
9148         0xfffe0101,                                     /* vs_1_1 */
9149         0x0000001f, 0x80000000, 0x900f0000,             /* dcl_position v0 */
9150         0x0000001f, 0x8000000a, 0x900f0001,             /* dcl_color0 v1 */
9151         0x0000001f, 0x80000005, 0x900f0002,             /* dcl_texcoord v2 */
9152         0x00000001, 0x800f0000, 0x90e40000,             /* mov r0, v0 */
9153         0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
9154         0x00000001, 0xd00f0000, 0x90e40001,             /* mov oD0, v1 */
9155         0x0000ffff
9156     };
9157
9158     const float quad[][3] =
9159     {
9160         {-0.5f, -0.5f,  1.1f}, /*0 */
9161         {-0.5f,  0.5f,  1.1f}, /*1 */
9162         { 0.5f, -0.5f,  1.1f}, /*2 */
9163         { 0.5f,  0.5f,  1.1f}, /*3 */
9164     };
9165
9166     const float vertcolor[][4] =
9167     {
9168         {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9169         {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9170         {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9171         {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9172     };
9173
9174     /* 4 position for 4 instances */
9175     const float instancepos[][3] =
9176     {
9177         {-0.6f,-0.6f, 0.0f},
9178         { 0.6f,-0.6f, 0.0f},
9179         { 0.6f, 0.6f, 0.0f},
9180         {-0.6f, 0.6f, 0.0f},
9181     };
9182
9183     short indices[] = {0, 1, 2, 1, 2, 3};
9184
9185     D3DVERTEXELEMENT9 decl[] =
9186     {
9187         {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9188         {1, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9189         {2, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9190         D3DDECL_END()
9191     };
9192
9193     /* set the default value because it isn't done in wine? */
9194     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9195     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9196
9197     /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9198     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9199     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9200
9201     /* check wrong cases */
9202     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9203     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9204     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9205     ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9206     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9207     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9208     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9209     ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9210     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9211     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9212     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9213     ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9214     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9215     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9216     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9217     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9218     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9219     ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9220     hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9221     ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9222
9223     /* set the default value back */
9224     hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9225     ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9226
9227     /* create all VertexBuffers*/
9228     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9229     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9230     if(!vb) {
9231         skip("Failed to create a vertex buffer\n");
9232         return;
9233     }
9234     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9235     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9236     if(!vb2) {
9237         skip("Failed to create a vertex buffer\n");
9238         goto out;
9239     }
9240     hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9241     ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9242     if(!vb3) {
9243         skip("Failed to create a vertex buffer\n");
9244         goto out;
9245     }
9246
9247     /* create IndexBuffer*/
9248     hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9249     ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9250     if(!ib) {
9251         skip("Failed to create a index buffer\n");
9252         goto out;
9253     }
9254
9255     /* copy all Buffers (Vertex + Index)*/
9256     hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9257     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9258     memcpy(data, quad, sizeof(quad));
9259     hr = IDirect3DVertexBuffer9_Unlock(vb);
9260     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9261     hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9262     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9263     memcpy(data, vertcolor, sizeof(vertcolor));
9264     hr = IDirect3DVertexBuffer9_Unlock(vb2);
9265     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9266     hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9267     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9268     memcpy(data, instancepos, sizeof(instancepos));
9269     hr = IDirect3DVertexBuffer9_Unlock(vb3);
9270     ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9271     hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9272     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9273     memcpy(data, indices, sizeof(indices));
9274     hr = IDirect3DIndexBuffer9_Unlock(ib);
9275     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9276
9277     /* create VertexShader */
9278     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9279     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9280     if(!shader) {
9281         skip("Failed to create a vetex shader\n");
9282         goto out;
9283     }
9284
9285     hr = IDirect3DDevice9_SetVertexShader(device, shader);
9286     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9287
9288     hr = IDirect3DDevice9_SetIndices(device, ib);
9289     ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9290
9291     /* run all tests */
9292     for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9293     {
9294         struct testdata act = testcases[i];
9295         decl[0].Stream = act.strVertex;
9296         decl[1].Stream = act.strColor;
9297         decl[2].Stream = act.strInstance;
9298         /* create VertexDeclarations */
9299         hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9300         ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9301
9302         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9303         ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9304
9305         hr = IDirect3DDevice9_BeginScene(device);
9306         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9307         if(SUCCEEDED(hr))
9308         {
9309             hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9310             ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9311
9312             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9313             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9314             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9315             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9316
9317             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9318             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9319             hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9320             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9321
9322             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9323             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9324             hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9325             ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9326
9327             hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
9328             ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9329             hr = IDirect3DDevice9_EndScene(device);
9330             ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9331
9332             /* set all StreamSource && StreamSourceFreq back to default */
9333             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9334             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9335             hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9336             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9337             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9338             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9339             hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9340             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9341             hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9342             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9343             hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9344             ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9345         }
9346
9347         hr = IDirect3DVertexDeclaration9_Release(pDecl);
9348         ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9349
9350         color = getPixelColor(device, 160, 360);
9351         ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9352         color = getPixelColor(device, 480, 360);
9353         ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9354         color = getPixelColor(device, 480, 120);
9355         ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9356         color = getPixelColor(device, 160, 120);
9357         ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9358
9359         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9360         ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9361     }
9362
9363     hr = IDirect3DDevice9_SetIndices(device, NULL);
9364     ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9365
9366 out:
9367     if(vb) IDirect3DVertexBuffer9_Release(vb);
9368     if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9369     if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9370     if(ib)IDirect3DIndexBuffer9_Release(ib);
9371     if(shader)IDirect3DVertexShader9_Release(shader);
9372 }
9373
9374 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9375     IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9376     IDirect3DTexture9 *dsttex = NULL;
9377     HRESULT hr;
9378     DWORD color;
9379     D3DRECT r1 = {0,  0,  50,  50 };
9380     D3DRECT r2 = {50, 0,  100, 50 };
9381     D3DRECT r3 = {50, 50, 100, 100};
9382     D3DRECT r4 = {0,  50,  50, 100};
9383     const float quad[] = {
9384         -1.0,   -1.0,   0.1,    0.0,    0.0,
9385          1.0,   -1.0,   0.1,    1.0,    0.0,
9386         -1.0,    1.0,   0.1,    0.0,    1.0,
9387          1.0,    1.0,   0.1,    1.0,    1.0,
9388     };
9389
9390     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9391     ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9392
9393     hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9394     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9395     hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9396     ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9397
9398     if(!src || !dsttex) {
9399         skip("One or more test resources could not be created\n");
9400         goto cleanup;
9401     }
9402
9403     hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9404     ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9405
9406     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9407     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9408
9409     /* Clear the StretchRect destination for debugging */
9410     hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9411     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9412     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9413     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9414
9415     hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9416     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9417
9418     hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9419     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9420     hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9421     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9422     hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9423     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9424     hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9425     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9426
9427     /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9428      * the target -> texture GL blit path
9429      */
9430     hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9431     ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9432     IDirect3DSurface9_Release(dst);
9433
9434     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9435     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9436
9437     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9438     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9439     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9440     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9441     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9442     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9443     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9444     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9445
9446     hr = IDirect3DDevice9_BeginScene(device);
9447     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9448     if(SUCCEEDED(hr)) {
9449         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9450         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9451         hr = IDirect3DDevice9_EndScene(device);
9452         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9453     }
9454
9455     color = getPixelColor(device, 160, 360);
9456     ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9457     color = getPixelColor(device, 480, 360);
9458     ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9459     color = getPixelColor(device, 480, 120);
9460     ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9461     color = getPixelColor(device, 160, 120);
9462     ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9463     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9464     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9465
9466     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9467     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9468     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9469     ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9470
9471 cleanup:
9472     if(src) IDirect3DSurface9_Release(src);
9473     if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9474     if(dsttex) IDirect3DTexture9_Release(dsttex);
9475 }
9476
9477 static void texop_test(IDirect3DDevice9 *device)
9478 {
9479     IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9480     IDirect3DTexture9 *texture = NULL;
9481     D3DLOCKED_RECT locked_rect;
9482     D3DCOLOR color;
9483     D3DCAPS9 caps;
9484     HRESULT hr;
9485     unsigned i;
9486
9487     static const struct {
9488         float x, y, z;
9489         float s, t;
9490         D3DCOLOR diffuse;
9491     } quad[] = {
9492         {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9493         {-1.0f,  1.0f, 0.1f, -1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9494         { 1.0f, -1.0f, 0.1f,  1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9495         { 1.0f,  1.0f, 0.1f,  1.0f,  1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9496     };
9497
9498     static const D3DVERTEXELEMENT9 decl_elements[] = {
9499         {0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9500         {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9501         {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9502         D3DDECL_END()
9503     };
9504
9505     static const struct {
9506         D3DTEXTUREOP op;
9507         const char *name;
9508         DWORD caps_flag;
9509         D3DCOLOR result;
9510     } test_data[] = {
9511         {D3DTOP_SELECTARG1,                "SELECTARG1",                D3DTEXOPCAPS_SELECTARG1,                D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9512         {D3DTOP_SELECTARG2,                "SELECTARG2",                D3DTEXOPCAPS_SELECTARG2,                D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9513         {D3DTOP_MODULATE,                  "MODULATE",                  D3DTEXOPCAPS_MODULATE,                  D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9514         {D3DTOP_MODULATE2X,                "MODULATE2X",                D3DTEXOPCAPS_MODULATE2X,                D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9515         {D3DTOP_MODULATE4X,                "MODULATE4X",                D3DTEXOPCAPS_MODULATE4X,                D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9516         {D3DTOP_ADD,                       "ADD",                       D3DTEXOPCAPS_ADD,                       D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9517         {D3DTOP_ADDSIGNED,                 "ADDSIGNED",                 D3DTEXOPCAPS_ADDSIGNED,                 D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9518         {D3DTOP_ADDSIGNED2X,               "ADDSIGNED2X",               D3DTEXOPCAPS_ADDSIGNED2X,               D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9519         {D3DTOP_SUBTRACT,                  "SUBTRACT",                  D3DTEXOPCAPS_SUBTRACT,                  D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9520         {D3DTOP_ADDSMOOTH,                 "ADDSMOOTH",                 D3DTEXOPCAPS_ADDSMOOTH,                 D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9521         {D3DTOP_BLENDDIFFUSEALPHA,         "BLENDDIFFUSEALPHA",         D3DTEXOPCAPS_BLENDDIFFUSEALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9522         {D3DTOP_BLENDTEXTUREALPHA,         "BLENDTEXTUREALPHA",         D3DTEXOPCAPS_BLENDTEXTUREALPHA,         D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9523         {D3DTOP_BLENDFACTORALPHA,          "BLENDFACTORALPHA",          D3DTEXOPCAPS_BLENDFACTORALPHA,          D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9524         {D3DTOP_BLENDTEXTUREALPHAPM,       "BLENDTEXTUREALPHAPM",       D3DTEXOPCAPS_BLENDTEXTUREALPHAPM,       D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9525         {D3DTOP_BLENDCURRENTALPHA,         "BLENDCURRENTALPHA",         D3DTEXOPCAPS_BLENDCURRENTALPHA,         D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9526         {D3DTOP_MODULATEALPHA_ADDCOLOR,    "MODULATEALPHA_ADDCOLOR",    D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR,    D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9527         {D3DTOP_MODULATECOLOR_ADDALPHA,    "MODULATECOLOR_ADDALPHA",    D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA,    D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9528         {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9529         {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9530         /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9531         {D3DTOP_DOTPRODUCT3,               "DOTPRODUCT3",               D3DTEXOPCAPS_DOTPRODUCT3,               D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9532         {D3DTOP_MULTIPLYADD,               "MULTIPLYADD",               D3DTEXOPCAPS_MULTIPLYADD,               D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9533         {D3DTOP_LERP,                      "LERP",                      D3DTEXOPCAPS_LERP,                      D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9534     };
9535
9536     memset(&caps, 0, sizeof(caps));
9537     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9538     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9539
9540     hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9541     ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9542     hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9543     ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9544
9545     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9546     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9547     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9548     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9549     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9550     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9551     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9552     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9553     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9554
9555     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9556     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9557     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9558     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9559     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9560     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9561
9562     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9563     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9564
9565     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9566     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9567     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9568     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9569     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9570     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9571
9572     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9573     ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9574
9575     for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9576     {
9577         if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9578         {
9579             skip("tex operation %s not supported\n", test_data[i].name);
9580             continue;
9581         }
9582
9583         hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9584         ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9585
9586         hr = IDirect3DDevice9_BeginScene(device);
9587         ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9588
9589         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9590         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9591
9592         hr = IDirect3DDevice9_EndScene(device);
9593         ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9594
9595         color = getPixelColor(device, 320, 240);
9596         ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9597                 test_data[i].name, color, test_data[i].result);
9598
9599         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9600         ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9601     }
9602
9603     if (texture) IDirect3DTexture9_Release(texture);
9604     if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9605 }
9606
9607 static void yuv_color_test(IDirect3DDevice9 *device) {
9608     HRESULT hr;
9609     IDirect3DSurface9 *surface = NULL, *target = NULL;
9610     unsigned int fmt, i;
9611     D3DFORMAT format;
9612     const char *fmt_string;
9613     D3DLOCKED_RECT lr;
9614     IDirect3D9 *d3d;
9615     HRESULT color;
9616     DWORD ref_color_left, ref_color_right;
9617
9618     struct {
9619         DWORD in;           /* The input color */
9620         DWORD uyvy_left;    /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9621         DWORD uyvy_right;   /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9622         DWORD yuy2_left;    /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9623         DWORD yuy2_right;   /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9624     } test_data[] = {
9625     /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9626      * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9627      * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9628      * that
9629      */
9630       { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9631       { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9632       { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9633       { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9634       { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9635       { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9636       { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9637       { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9638       { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9639       { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9640       { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9641       { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9642       { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9643       { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9644
9645       { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9646       { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9647       { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9648       { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9649     };
9650
9651     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9652     ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9653     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9654     ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9655
9656     IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9657     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9658
9659     for(fmt = 0; fmt < 2; fmt++) {
9660         if(fmt == 0) {
9661             format = D3DFMT_UYVY;
9662             fmt_string = "D3DFMT_UYVY";
9663         } else {
9664             format = D3DFMT_YUY2;
9665             fmt_string = "D3DFMT_YUY2";
9666         }
9667
9668         /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9669                        * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9670                        */
9671         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9672                                         D3DRTYPE_SURFACE, format) != D3D_OK) {
9673             skip("%s is not supported\n", fmt_string);
9674             continue;
9675         }
9676
9677         /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9678         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9679         ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9680
9681         for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9682             if(fmt == 0) {
9683                 ref_color_left = test_data[i].uyvy_left;
9684                 ref_color_right = test_data[i].uyvy_right;
9685             } else {
9686                 ref_color_left = test_data[i].yuy2_left;
9687                 ref_color_right = test_data[i].yuy2_right;
9688             }
9689
9690             memset(&lr, 0, sizeof(lr));
9691             hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9692             ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9693             *((DWORD *) lr.pBits) = test_data[i].in;
9694             hr = IDirect3DSurface9_UnlockRect(surface);
9695             ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9696
9697             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9698             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9699             hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9700             ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9701
9702             /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9703              * prevent running into precision problems, read a far left and far right pixel. In the future we may
9704              * want to add tests for the filtered pixels as well.
9705              *
9706              * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9707              * differently, so we need a max diff of 16
9708              */
9709             color = getPixelColor(device, 40, 240);
9710             ok(color_match(color, ref_color_left, 18),
9711                "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9712                test_data[i].in, color, ref_color_left, fmt_string);
9713             color = getPixelColor(device, 600, 240);
9714             ok(color_match(color, ref_color_right, 18),
9715                "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9716                test_data[i].in, color, ref_color_right, fmt_string);
9717             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9718             ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9719         }
9720         IDirect3DSurface9_Release(surface);
9721     }
9722     IDirect3DSurface9_Release(target);
9723     IDirect3D9_Release(d3d);
9724 }
9725
9726 static void texop_range_test(IDirect3DDevice9 *device)
9727 {
9728     static const struct {
9729         float x, y, z;
9730         D3DCOLOR diffuse;
9731     } quad[] = {
9732         {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9733         {-1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9734         { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9735         { 1.0f,  1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9736     };
9737     HRESULT hr;
9738     IDirect3DTexture9 *texture;
9739     D3DLOCKED_RECT locked_rect;
9740     D3DCAPS9 caps;
9741     DWORD color;
9742
9743     /* We need ADD and SUBTRACT operations */
9744     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9745     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9746     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9747         skip("D3DTOP_ADD is not supported, skipping value range test\n");
9748         return;
9749     }
9750     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9751         skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9752         return;
9753     }
9754
9755     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9756     ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9757     /* Stage 1: result = diffuse(=1.0) + diffuse
9758      * stage 2: result = result - tfactor(= 0.5)
9759      */
9760     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9761     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9762     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9763     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9764     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9765     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9766     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9767     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9768     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9769     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9770     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9771     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9772     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9773     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9774
9775     hr = IDirect3DDevice9_BeginScene(device);
9776     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9777     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9778     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9779     hr = IDirect3DDevice9_EndScene(device);
9780     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9781
9782     color = getPixelColor(device, 320, 240);
9783     ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9784        color);
9785     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9786     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9787
9788     hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9789     ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9790     hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9791     ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9792     *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9793     hr = IDirect3DTexture9_UnlockRect(texture, 0);
9794     ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9795     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9796     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9797
9798     /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9799      * stage 2: result = result + diffuse(1.0)
9800      */
9801     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9802     ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9803     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9804     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9805     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9806     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9807     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9808     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9809     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9810     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9811     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9812     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9813     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9814     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9815
9816     hr = IDirect3DDevice9_BeginScene(device);
9817     ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9818     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9819     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9820     hr = IDirect3DDevice9_EndScene(device);
9821     ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9822
9823     color = getPixelColor(device, 320, 240);
9824     ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9825        color);
9826     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9827     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9828
9829     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9830     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9831     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9832     ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9833     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9834     ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9835     IDirect3DTexture9_Release(texture);
9836 }
9837
9838 static void alphareplicate_test(IDirect3DDevice9 *device) {
9839     struct vertex quad[] = {
9840         { -1.0,    -1.0,    0.1,    0x80ff00ff },
9841         {  1.0,    -1.0,    0.1,    0x80ff00ff },
9842         { -1.0,     1.0,    0.1,    0x80ff00ff },
9843         {  1.0,     1.0,    0.1,    0x80ff00ff },
9844     };
9845     HRESULT hr;
9846     DWORD color;
9847
9848     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9849     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9850
9851     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9852     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9853
9854     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9855     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9856     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9857     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9858
9859     hr = IDirect3DDevice9_BeginScene(device);
9860     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9861     if(SUCCEEDED(hr)) {
9862         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9863         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9864         hr = IDirect3DDevice9_EndScene(device);
9865         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9866     }
9867
9868     color = getPixelColor(device, 320, 240);
9869     ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9870        color);
9871     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9872     ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9873
9874     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9875     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9876
9877 }
9878
9879 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9880     HRESULT hr;
9881     D3DCAPS9 caps;
9882     DWORD color;
9883     struct vertex quad[] = {
9884         { -1.0,    -1.0,    0.1,    0x408080c0 },
9885         {  1.0,    -1.0,    0.1,    0x408080c0 },
9886         { -1.0,     1.0,    0.1,    0x408080c0 },
9887         {  1.0,     1.0,    0.1,    0x408080c0 },
9888     };
9889
9890     memset(&caps, 0, sizeof(caps));
9891     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9892     ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9893     if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9894         skip("D3DTOP_DOTPRODUCT3 not supported\n");
9895         return;
9896     }
9897
9898     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9899     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9900
9901     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9902     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9903
9904     /* dp3_x4 r0, diffuse_bias, tfactor_bias
9905      * mov r0.a, diffuse.a
9906      * mov r0, r0.a
9907      *
9908      * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9909      * 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
9910      * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9911      */
9912     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9913     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9914     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9915     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9916     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9917     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9918     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9919     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9920     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9921     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9922     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9923     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9924     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9925     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9926     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9927     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9928     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9929     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9930
9931     hr = IDirect3DDevice9_BeginScene(device);
9932     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9933     if(SUCCEEDED(hr)) {
9934         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9935         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9936         hr = IDirect3DDevice9_EndScene(device);
9937         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
9938     }
9939
9940     color = getPixelColor(device, 320, 240);
9941     ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9942        color);
9943     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9944     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9945
9946     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9947     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9948     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9949     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9950     hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9951     ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9952 }
9953
9954 static void zwriteenable_test(IDirect3DDevice9 *device) {
9955     HRESULT hr;
9956     DWORD color;
9957     struct vertex quad1[] = {
9958         { -1.0,  -1.0,  0.1,    0x00ff0000},
9959         { -1.0,   1.0,  0.1,    0x00ff0000},
9960         {  1.0,  -1.0,  0.1,    0x00ff0000},
9961         {  1.0,   1.0,  0.1,    0x00ff0000},
9962     };
9963     struct vertex quad2[] = {
9964         { -1.0,  -1.0,  0.9,    0x0000ff00},
9965         { -1.0,   1.0,  0.9,    0x0000ff00},
9966         {  1.0,  -1.0,  0.9,    0x0000ff00},
9967         {  1.0,   1.0,  0.9,    0x0000ff00},
9968     };
9969
9970     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9971     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9972
9973     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9974     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9975     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9976     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9977     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9978     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9979     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9980     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9981
9982     hr = IDirect3DDevice9_BeginScene(device);
9983     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9984     if(SUCCEEDED(hr)) {
9985         /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9986          * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9987          * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9988          * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9989          * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9990          * the screen is green, so zenable = D3DZB_FALSE and zwriteenable  = TRUE does NOT write to the z buffer.
9991          */
9992         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9993         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9994         hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9995         ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9996         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9997         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9998
9999         hr = IDirect3DDevice9_EndScene(device);
10000         ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10001     }
10002
10003     color = getPixelColor(device, 320, 240);
10004     ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
10005        color);
10006     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10007     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10008
10009     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10010     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10011 }
10012
10013 static void alphatest_test(IDirect3DDevice9 *device) {
10014 #define ALPHATEST_PASSED 0x0000ff00
10015 #define ALPHATEST_FAILED 0x00ff0000
10016     struct {
10017         D3DCMPFUNC  func;
10018         DWORD       color_less;
10019         DWORD       color_equal;
10020         DWORD       color_greater;
10021     } testdata[] = {
10022         {   D3DCMP_NEVER,           ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10023         {   D3DCMP_LESS,            ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED },
10024         {   D3DCMP_EQUAL,           ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10025         {   D3DCMP_LESSEQUAL,       ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED },
10026         {   D3DCMP_GREATER,         ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10027         {   D3DCMP_NOTEQUAL,        ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED },
10028         {   D3DCMP_GREATEREQUAL,    ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10029         {   D3DCMP_ALWAYS,          ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED },
10030     };
10031     unsigned int i, j;
10032     HRESULT hr;
10033     DWORD color;
10034     struct vertex quad[] = {
10035         {   -1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10036         {    1.0,    -1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10037         {   -1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10038         {    1.0,     1.0,   0.1,    ALPHATEST_PASSED | 0x80000000  },
10039     };
10040     D3DCAPS9 caps;
10041
10042     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10043     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10044     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10045     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10046
10047     for(j = 0; j < 2; j++) {
10048         if(j == 1) {
10049             /* Try a pixel shader instead of fixed function. The wined3d code may emulate
10050              * the alpha test either for performance reasons(floating point RTs) or to work
10051              * around driver bugs(Geforce 7x00 cards on MacOS). There may be a different
10052              * codepath for ffp and shader in this case, and the test should cover both
10053              */
10054             IDirect3DPixelShader9 *ps;
10055             DWORD shader_code[] = {
10056                 0xffff0101,                                 /* ps_1_1           */
10057                 0x00000001, 0x800f0000, 0x90e40000,         /* mov r0, v0       */
10058                 0x0000ffff                                  /* end              */
10059             };
10060             memset(&caps, 0, sizeof(caps));
10061             IDirect3DDevice9_GetDeviceCaps(device, &caps);
10062             ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
10063             if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
10064                 break;
10065             }
10066
10067             hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
10068             ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
10069             IDirect3DDevice9_SetPixelShader(device, ps);
10070             ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10071             IDirect3DPixelShader9_Release(ps);
10072         }
10073
10074         for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
10075             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
10076             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState 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, 0x90);
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_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
10092             color, testdata[i].color_less, 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, 0x80);
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_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
10110             color, testdata[i].color_equal, 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             hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
10115             ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10116             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10117             ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10118             hr = IDirect3DDevice9_BeginScene(device);
10119             ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
10120             if(SUCCEEDED(hr)) {
10121                 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10122                 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
10123                 hr = IDirect3DDevice9_EndScene(device);
10124                 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10125             }
10126             color = getPixelColor(device, 320, 240);
10127             ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
10128             color, testdata[i].color_greater, testdata[i].func);
10129             hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10130             ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
10131         }
10132     }
10133
10134     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
10135     ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
10136     IDirect3DDevice9_SetPixelShader(device, NULL);
10137     ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
10138 }
10139
10140 static void sincos_test(IDirect3DDevice9 *device) {
10141     const DWORD sin_shader_code[] = {
10142         0xfffe0200,                                                                 /* vs_2_0                       */
10143         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10144         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10145         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10146         0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.y, r1.x, c0, c1    */
10147         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10148         0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002,                             /* mul oPos.y, r0.y, c2.w       */
10149         0x02000001, 0xd00f0000, 0xa0a60002,                                         /* mov oD0, c2.zyzz             */
10150         0x0000ffff                                                                  /* end                          */
10151     };
10152     const DWORD cos_shader_code[] = {
10153         0xfffe0200,                                                                 /* vs_2_0                       */
10154         0x0200001f, 0x80000000, 0x900f0000,                                         /* dcl_position v0              */
10155         0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a,     /* def c2, 3.14159, 1, 0, 0.85  */
10156         0x03000005, 0x80010001, 0x90000000, 0xa0000002,                             /* mul r1.x, v0.x, c2.x         */
10157         0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001,                 /* sincos r0.x, r1.x, c0, c1    */
10158         0x02000001, 0xc00d0000, 0x90e40000,                                         /* mov oPos.xzw, v0             */
10159         0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002,                             /* mul oPos.y, r0.x, c2.w       */
10160         0x02000001, 0xd00f0000, 0xa0a90002,                                         /* mov oD0, c2.yzzz             */
10161         0x0000ffff                                                                  /* end                          */
10162     };
10163     IDirect3DVertexShader9 *sin_shader, *cos_shader;
10164     HRESULT hr;
10165     struct {
10166         float x, y, z;
10167     } data[1280];
10168     unsigned int i;
10169     float sincosc1[4] = {D3DSINCOSCONST1};
10170     float sincosc2[4] = {D3DSINCOSCONST2};
10171
10172     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
10173     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10174
10175     hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
10176     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10177     hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
10178     ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
10179     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10180     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
10181     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
10182     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10183     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
10184     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
10185
10186     /* Generate a point from -1 to 1 every 0.5 pixels */
10187     for(i = 0; i < 1280; i++) {
10188         data[i].x = (-640.0 + i) / 640.0;
10189         data[i].y = 0.0;
10190         data[i].z = 0.1;
10191     }
10192
10193     hr = IDirect3DDevice9_BeginScene(device);
10194     if(SUCCEEDED(hr)) {
10195         hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
10196         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10197         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10198         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10199
10200         hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
10201         ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with 0x%08x\n", hr);
10202         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
10203         ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with 0x%08x\n", hr);
10204
10205         hr = IDirect3DDevice9_EndScene(device);
10206         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with 0x%08x\n", hr);
10207     }
10208     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10209     ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
10210     /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
10211
10212     IDirect3DDevice9_SetVertexShader(device, NULL);
10213     IDirect3DVertexShader9_Release(sin_shader);
10214     IDirect3DVertexShader9_Release(cos_shader);
10215 }
10216
10217 static void loop_index_test(IDirect3DDevice9 *device) {
10218     const DWORD shader_code[] = {
10219         0xfffe0200,                                                 /* vs_2_0                   */
10220         0x0200001f, 0x80000000, 0x900f0000,                         /* dcl_position v0          */
10221         0x02000001, 0x800f0000, 0xa0e40000,                         /* mov r0, c0               */
10222         0x0200001b, 0xf0e40800, 0xf0e40000,                         /* loop aL, i0              */
10223         0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1]    */
10224         0x0000001d,                                                 /* endloop                  */
10225         0x02000001, 0xc00f0000, 0x90e40000,                         /* mov oPos, v0             */
10226         0x02000001, 0xd00f0000, 0x80e40000,                         /* mov oD0, r0              */
10227         0x0000ffff                                                  /* END                      */
10228     };
10229     IDirect3DVertexShader9 *shader;
10230     HRESULT hr;
10231     DWORD color;
10232     const float quad[] = {
10233         -1.0,   -1.0,   0.1,
10234          1.0,   -1.0,   0.1,
10235         -1.0,    1.0,   0.1,
10236          1.0,    1.0,   0.1
10237     };
10238     const float zero[4] = {0, 0, 0, 0};
10239     const float one[4] = {1, 1, 1, 1};
10240     int i0[4] = {2, 10, -3, 0};
10241     float values[4];
10242
10243     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10244     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10245     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10246     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10247     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10248     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10249     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10250     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10251
10252     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
10253     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10254     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
10255     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10256     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
10257     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10258     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
10259     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10260     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
10261     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10262     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
10263     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10264     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
10265     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10266     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
10267     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10268     values[0] = 1.0;
10269     values[1] = 1.0;
10270     values[2] = 0.0;
10271     values[3] = 0.0;
10272     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
10273     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10274     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
10275     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10276     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
10277     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10278     values[0] = -1.0;
10279     values[1] = 0.0;
10280     values[2] = 0.0;
10281     values[3] = 0.0;
10282     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
10283     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10284     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
10285     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10286     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
10287     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10288     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
10289     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10290     hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
10291     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
10292
10293     hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
10294     ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
10295
10296     hr = IDirect3DDevice9_BeginScene(device);
10297     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10298     if(SUCCEEDED(hr))
10299     {
10300         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10301         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10302         hr = IDirect3DDevice9_EndScene(device);
10303         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10304     }
10305     color = getPixelColor(device, 320, 240);
10306     ok(color_match(color, 0x0000ff00, 1),
10307        "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
10308     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10309     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10310
10311     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10312     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10313     IDirect3DVertexShader9_Release(shader);
10314 }
10315
10316 static void sgn_test(IDirect3DDevice9 *device) {
10317     const DWORD shader_code[] = {
10318         0xfffe0200,                                                             /* vs_2_0                       */
10319         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position o0              */
10320         0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
10321         0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0   */
10322         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
10323         0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002,             /* sgn r0, c0, r1, r2           */
10324         0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001,                         /* add oD0, r0, c1              */
10325         0x0000ffff                                                              /* end                          */
10326     };
10327     IDirect3DVertexShader9 *shader;
10328     HRESULT hr;
10329     DWORD color;
10330     const float quad[] = {
10331         -1.0,   -1.0,   0.1,
10332          1.0,   -1.0,   0.1,
10333         -1.0,    1.0,   0.1,
10334          1.0,    1.0,   0.1
10335     };
10336
10337     hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10338     ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
10339     hr = IDirect3DDevice9_SetVertexShader(device, shader);
10340     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10341     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10342     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
10343     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10344     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10345
10346     hr = IDirect3DDevice9_BeginScene(device);
10347     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10348     if(SUCCEEDED(hr))
10349     {
10350         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10351         ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
10352         hr = IDirect3DDevice9_EndScene(device);
10353         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10354     }
10355     color = getPixelColor(device, 320, 240);
10356     ok(color_match(color, 0x008000ff, 1),
10357        "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
10358     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10359     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10360
10361     hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10362     ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
10363     IDirect3DVertexShader9_Release(shader);
10364 }
10365
10366 static void viewport_test(IDirect3DDevice9 *device) {
10367     HRESULT hr;
10368     DWORD color;
10369     D3DVIEWPORT9 vp, old_vp;
10370     BOOL draw_failed = TRUE;
10371     const float quad[] =
10372     {
10373         -0.5,   -0.5,   0.1,
10374          0.5,   -0.5,   0.1,
10375         -0.5,    0.5,   0.1,
10376          0.5,    0.5,   0.1
10377     };
10378
10379     memset(&old_vp, 0, sizeof(old_vp));
10380     hr = IDirect3DDevice9_GetViewport(device, &old_vp);
10381     ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
10382
10383     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
10384     ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10385
10386     /* Test a viewport with Width and Height bigger than the surface dimensions
10387      *
10388      * TODO: Test Width < surface.width, but X + Width > surface.width
10389      * TODO: Test Width < surface.width, what happens with the height?
10390      *
10391      * Note that Windows 7 rejects MinZ / MaxZ outside [0;1], but accepts Width
10392      * and Height fields bigger than the framebuffer. However, it later refuses
10393      * to draw.
10394      */
10395     memset(&vp, 0, sizeof(vp));
10396     vp.X = 0;
10397     vp.Y = 0;
10398     vp.Width = 10000;
10399     vp.Height = 10000;
10400     vp.MinZ = 0.0;
10401     vp.MaxZ = 0.0;
10402     hr = IDirect3DDevice9_SetViewport(device, &vp);
10403     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10404
10405     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10406     ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
10407     hr = IDirect3DDevice9_BeginScene(device);
10408     ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
10409     if(SUCCEEDED(hr))
10410     {
10411         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
10412         ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "DrawPrimitiveUP failed (%08x)\n", hr);
10413         draw_failed = FAILED(hr);
10414         hr = IDirect3DDevice9_EndScene(device);
10415         ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
10416     }
10417
10418     if(!draw_failed)
10419     {
10420         color = getPixelColor(device, 158, 118);
10421         ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
10422         color = getPixelColor(device, 162, 118);
10423         ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
10424         color = getPixelColor(device, 158, 122);
10425         ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
10426         color = getPixelColor(device, 162, 122);
10427         ok(color == 0x00ffffff, "viewport test: (162,122) has color %08x\n", color);
10428
10429         color = getPixelColor(device, 478, 358);
10430         ok(color == 0x00ffffff, "viewport test: (478,358 has color %08x\n", color);
10431         color = getPixelColor(device, 482, 358);
10432         ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
10433         color = getPixelColor(device, 478, 362);
10434         ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
10435         color = getPixelColor(device, 482, 362);
10436         ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
10437     }
10438
10439     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10440     ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10441
10442     hr = IDirect3DDevice9_SetViewport(device, &old_vp);
10443     ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
10444 }
10445
10446 /* This test tests depth clamping / clipping behaviour:
10447  *   - When D3DRS_CLIPPING is disabled depth values are *clamped* to the
10448  *   minimum/maximum z value.
10449  *   - The viewport's MinZ/MaxZ is irrelevant for this.
10450  *   - When D3DRS_CLIPPING is enabled depth values are clipped.
10451  *   - Pretransformed vertices behave the same as regular vertices.
10452  */
10453 static void depth_clamp_test(IDirect3DDevice9 *device)
10454 {
10455     const struct tvertex quad1[] =
10456     {
10457         {    0,    0,  5.0f, 1.0, 0xff002b7f},
10458         {  640,    0,  5.0f, 1.0, 0xff002b7f},
10459         {    0,  480,  5.0f, 1.0, 0xff002b7f},
10460         {  640,  480,  5.0f, 1.0, 0xff002b7f},
10461     };
10462     const struct tvertex quad2[] =
10463     {
10464         {    0,  300, 10.0f, 1.0, 0xfff9e814},
10465         {  640,  300, 10.0f, 1.0, 0xfff9e814},
10466         {    0,  360, 10.0f, 1.0, 0xfff9e814},
10467         {  640,  360, 10.0f, 1.0, 0xfff9e814},
10468     };
10469     const struct vertex quad3[] =
10470     {
10471         {-0.65, 0.55,  5.0f,      0xffffffff},
10472         {-0.35, 0.55,  5.0f,      0xffffffff},
10473         {-0.65, 0.15,  5.0f,      0xffffffff},
10474         {-0.35, 0.15,  5.0f,      0xffffffff},
10475     };
10476     const struct vertex quad4[] =
10477     {
10478         {-0.87, 0.83, 10.0f,      0xffffffff},
10479         {-0.65, 0.83, 10.0f,      0xffffffff},
10480         {-0.87, 0.55, 10.0f,      0xffffffff},
10481         {-0.65, 0.55, 10.0f,      0xffffffff},
10482     };
10483     const struct vertex quad5[] =
10484     {
10485         { -0.5,  0.5, 10.0f,      0xff14f914},
10486         {  0.5,  0.5, 10.0f,      0xff14f914},
10487         { -0.5, -0.5, 10.0f,      0xff14f914},
10488         {  0.5, -0.5, 10.0f,      0xff14f914},
10489     };
10490     const struct tvertex quad6[] =
10491     {
10492         {    0,  120, 10.0f, 1.0, 0xfff91414},
10493         {  640,  120, 10.0f, 1.0, 0xfff91414},
10494         {    0,  180, 10.0f, 1.0, 0xfff91414},
10495         {  640,  180, 10.0f, 1.0, 0xfff91414},
10496     };
10497
10498     D3DVIEWPORT9 vp;
10499     D3DCOLOR color;
10500     HRESULT hr;
10501
10502     vp.X = 0;
10503     vp.Y = 0;
10504     vp.Width = 640;
10505     vp.Height = 480;
10506     vp.MinZ = 0.0;
10507     vp.MaxZ = 7.5;
10508
10509     hr = IDirect3DDevice9_SetViewport(device, &vp);
10510     if(FAILED(hr))
10511     {
10512         /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
10513          * the tests because the 7.5 is just intended to show that it doesn't have
10514          * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
10515          * viewport and continue.
10516          */
10517         ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
10518         vp.MaxZ = 1.0;
10519         hr = IDirect3DDevice9_SetViewport(device, &vp);
10520     }
10521     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10522
10523     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10524     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10525
10526     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10527     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10528     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10529     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10530     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10531     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10532     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10533     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10534
10535     hr = IDirect3DDevice9_BeginScene(device);
10536     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10537
10538     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10539     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10540
10541     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10542     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10543     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10544     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10545
10546     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10547     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10548
10549     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10550     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10551     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
10552     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10553
10554     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
10555     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10556
10557     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
10558     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10559
10560     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10561     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10562
10563     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
10564     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10565
10566     hr = IDirect3DDevice9_EndScene(device);
10567     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10568
10569     color = getPixelColor(device, 75, 75);
10570     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10571     color = getPixelColor(device, 150, 150);
10572     ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
10573     color = getPixelColor(device, 320, 240);
10574     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10575     color = getPixelColor(device, 320, 330);
10576     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10577     color = getPixelColor(device, 320, 330);
10578     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10579
10580     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10581     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10582
10583     vp.MinZ = 0.0;
10584     vp.MaxZ = 1.0;
10585     hr = IDirect3DDevice9_SetViewport(device, &vp);
10586     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10587 }
10588
10589 static void depth_bounds_test(IDirect3DDevice9 *device)
10590 {
10591     const struct tvertex quad1[] =
10592     {
10593         {    0,    0, 0.0f, 1, 0xfff9e814},
10594         {  640,    0, 0.0f, 1, 0xfff9e814},
10595         {    0,  480, 1.0f, 1, 0xfff9e814},
10596         {  640,  480, 1.0f, 1, 0xfff9e814},
10597     };
10598     const struct tvertex quad2[] =
10599     {
10600         {    0,    0,  0.6f, 1, 0xff002b7f},
10601         {  640,    0,  0.6f, 1, 0xff002b7f},
10602         {    0,  480,  0.6f, 1, 0xff002b7f},
10603         {  640,  480,  0.6f, 1, 0xff002b7f},
10604     };
10605     const struct tvertex quad3[] =
10606     {
10607         {    0,  100, 0.6f, 1, 0xfff91414},
10608         {  640,  100, 0.6f, 1, 0xfff91414},
10609         {    0,  160, 0.6f, 1, 0xfff91414},
10610         {  640,  160, 0.6f, 1, 0xfff91414},
10611     };
10612
10613     union {
10614         DWORD d;
10615         float f;
10616     } tmpvalue;
10617
10618     IDirect3D9 *d3d = NULL;
10619     IDirect3DSurface9 *offscreen_surface = NULL;
10620     D3DCOLOR color;
10621     HRESULT hr;
10622
10623     IDirect3DDevice9_GetDirect3D(device, &d3d);
10624     if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10625             0,  D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK) {
10626         skip("No NVDB (depth bounds test) support\n");
10627         IDirect3D9_Release(d3d);
10628         return;
10629     }
10630     IDirect3D9_Release(d3d);
10631
10632     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
10633             MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
10634     ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
10635     if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
10636
10637     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
10638     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10639
10640     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10641     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10642     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
10643     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10644     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10645     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10646     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10647     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10648
10649
10650     hr = IDirect3DDevice9_BeginScene(device);
10651     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10652
10653     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
10654     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10655
10656     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10657     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10658
10659     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
10660     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10661
10662     tmpvalue.f = 0.625;
10663     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10664     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10665
10666     tmpvalue.f = 0.75;
10667     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
10668     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10669
10670     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10671     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10672
10673     tmpvalue.f = 0.75;
10674     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
10675     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10676
10677     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10678     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10679
10680     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
10681     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10682
10683     hr = IDirect3DDevice9_EndScene(device);
10684     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10685
10686     color = getPixelColor(device, 150, 130);
10687     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10688     color = getPixelColor(device, 150, 200);
10689     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10690     color = getPixelColor(device, 150, 300-5);
10691     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10692     color = getPixelColor(device, 150, 300+5);
10693     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10694     color = getPixelColor(device, 150, 330);
10695     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
10696     color = getPixelColor(device, 150, 360-5);
10697     ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
10698     color = getPixelColor(device, 150, 360+5);
10699     ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
10700
10701     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10702     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10703 }
10704
10705 static void depth_buffer_test(IDirect3DDevice9 *device)
10706 {
10707     static const struct vertex quad1[] =
10708     {
10709         { -1.0,  1.0, 0.33f, 0xff00ff00},
10710         {  1.0,  1.0, 0.33f, 0xff00ff00},
10711         { -1.0, -1.0, 0.33f, 0xff00ff00},
10712         {  1.0, -1.0, 0.33f, 0xff00ff00},
10713     };
10714     static const struct vertex quad2[] =
10715     {
10716         { -1.0,  1.0, 0.50f, 0xffff00ff},
10717         {  1.0,  1.0, 0.50f, 0xffff00ff},
10718         { -1.0, -1.0, 0.50f, 0xffff00ff},
10719         {  1.0, -1.0, 0.50f, 0xffff00ff},
10720     };
10721     static const struct vertex quad3[] =
10722     {
10723         { -1.0,  1.0, 0.66f, 0xffff0000},
10724         {  1.0,  1.0, 0.66f, 0xffff0000},
10725         { -1.0, -1.0, 0.66f, 0xffff0000},
10726         {  1.0, -1.0, 0.66f, 0xffff0000},
10727     };
10728     static const DWORD expected_colors[4][4] =
10729     {
10730         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10731         {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
10732         {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
10733         {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
10734     };
10735
10736     IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
10737     unsigned int i, j;
10738     D3DVIEWPORT9 vp;
10739     D3DCOLOR color;
10740     HRESULT hr;
10741
10742     vp.X = 0;
10743     vp.Y = 0;
10744     vp.Width = 640;
10745     vp.Height = 480;
10746     vp.MinZ = 0.0;
10747     vp.MaxZ = 1.0;
10748
10749     hr = IDirect3DDevice9_SetViewport(device, &vp);
10750     ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
10751
10752     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10753     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10754     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10755     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10756     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10757     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10758     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
10759     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10760     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10761     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10762
10763     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10764     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10765     hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
10766             D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
10767     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10768     hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
10769             D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
10770     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10771     hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
10772             D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
10773     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10774
10775     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
10776     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10777     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
10778     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10779
10780     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10781     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10782     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10783     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10784
10785     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
10786     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10787     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
10788     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10789
10790     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
10791     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10792     hr = IDirect3DDevice9_BeginScene(device);
10793     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10794     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
10795     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10796     hr = IDirect3DDevice9_EndScene(device);
10797     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10798
10799     hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10800     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10801     IDirect3DSurface9_Release(backbuffer);
10802     IDirect3DSurface9_Release(rt3);
10803     IDirect3DSurface9_Release(rt2);
10804     IDirect3DSurface9_Release(rt1);
10805
10806     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
10807     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10808
10809     hr = IDirect3DDevice9_BeginScene(device);
10810     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10811     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
10812     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10813     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
10814     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10815     hr = IDirect3DDevice9_EndScene(device);
10816     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10817
10818     for (i = 0; i < 4; ++i)
10819     {
10820         for (j = 0; j < 4; ++j)
10821         {
10822             unsigned int x = 80 * ((2 * j) + 1);
10823             unsigned int y = 60 * ((2 * i) + 1);
10824             color = getPixelColor(device, x, y);
10825             ok(color_match(color, expected_colors[i][j], 0),
10826                     "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
10827         }
10828     }
10829
10830     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10831     ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10832 }
10833
10834 static void intz_test(IDirect3DDevice9 *device)
10835 {
10836     static const DWORD ps_code[] =
10837     {
10838         0xffff0200,                                                             /* ps_2_0                       */
10839         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
10840         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
10841         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
10842         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
10843         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
10844         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
10845         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
10846         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
10847         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
10848         0x0000ffff,                                                             /* end                          */
10849     };
10850     struct
10851     {
10852         float x, y, z;
10853         float s, t, p, q;
10854     }
10855     quad[] =
10856     {
10857         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
10858         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
10859         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
10860         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
10861     };
10862     struct
10863     {
10864         UINT x, y;
10865         D3DCOLOR color;
10866     }
10867     expected_colors[] =
10868     {
10869         {400,  60, D3DCOLOR_ARGB(0x00, 0x9f, 0xff, 0x00)},
10870         {560, 180, D3DCOLOR_ARGB(0x00, 0xdf, 0x55, 0x00)},
10871         {560, 300, D3DCOLOR_ARGB(0x00, 0xdf, 0x66, 0x00)},
10872         {400, 420, D3DCOLOR_ARGB(0x00, 0x9f, 0xb6, 0x00)},
10873         {240, 420, D3DCOLOR_ARGB(0x00, 0x60, 0x6d, 0x00)},
10874         { 80, 300, D3DCOLOR_ARGB(0x00, 0x20, 0x33, 0x00)},
10875         { 80, 180, D3DCOLOR_ARGB(0x00, 0x20, 0x55, 0x00)},
10876         {240,  60, D3DCOLOR_ARGB(0x00, 0x60, 0xff, 0x00)},
10877     };
10878
10879     IDirect3DSurface9 *original_ds, *original_rt, *rt;
10880     IDirect3DTexture9 *texture;
10881     IDirect3DPixelShader9 *ps;
10882     IDirect3DSurface9 *ds;
10883     IDirect3D9 *d3d9;
10884     D3DCAPS9 caps;
10885     HRESULT hr;
10886     UINT i;
10887
10888     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10889     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
10890     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
10891     {
10892         skip("No pixel shader 2.0 support, skipping INTZ test.\n");
10893         return;
10894     }
10895
10896     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
10897     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
10898
10899     hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
10900             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'));
10901     if (FAILED(hr))
10902     {
10903         skip("No INTZ support, skipping INTZ test.\n");
10904         return;
10905     }
10906
10907     IDirect3D9_Release(d3d9);
10908
10909     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
10910     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10911     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
10912     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
10913
10914     hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
10915             D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
10916     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
10917     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
10918             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
10919     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10920     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
10921     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
10922
10923     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
10924     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
10925     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
10926     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10927     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
10928     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10929     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
10930     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10931     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10932     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
10933
10934     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10935     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10936     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10937     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10938     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
10939     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10940     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
10941     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10942     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
10943     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
10944
10945     hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
10946     ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
10947     hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
10948     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10949     hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10950     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10951     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10952     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10953
10954     /* Setup the depth/stencil surface. */
10955     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
10956     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
10957
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     hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
10966     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10967     IDirect3DSurface9_Release(ds);
10968     hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
10969     ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
10970     hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
10971     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10972     hr = IDirect3DDevice9_SetPixelShader(device, ps);
10973     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
10974
10975     /* Read the depth values back. */
10976     hr = IDirect3DDevice9_BeginScene(device);
10977     ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
10978     hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10979     ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
10980     hr = IDirect3DDevice9_EndScene(device);
10981     ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
10982
10983     for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
10984     {
10985         D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
10986         ok(color_match(color, expected_colors[i].color, 1),
10987                 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
10988                 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
10989     }
10990
10991     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10992     ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
10993
10994     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
10995     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
10996     IDirect3DSurface9_Release(original_ds);
10997     hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
10998     ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
10999     IDirect3DTexture9_Release(texture);
11000     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11001     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11002     IDirect3DPixelShader9_Release(ps);
11003
11004     IDirect3DSurface9_Release(original_rt);
11005     IDirect3DSurface9_Release(rt);
11006 }
11007
11008 static void shadow_test(IDirect3DDevice9 *device)
11009 {
11010     static const DWORD ps_code[] =
11011     {
11012         0xffff0200,                                                             /* ps_2_0                       */
11013         0x0200001f, 0x90000000, 0xa00f0800,                                     /* dcl_2d s0                    */
11014         0x0200001f, 0x80000000, 0xb00f0000,                                     /* dcl t0                       */
11015         0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0   */
11016         0x02000001, 0x800f0001, 0xa0e40000,                                     /* mov r1, c0                   */
11017         0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texld r0, t0, s0             */
11018         0x02000001, 0x80010001, 0x80e40000,                                     /* mov r1.x, r0                 */
11019         0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800,                         /* texldp r0, t0, s0            */
11020         0x02000001, 0x80020001, 0x80000000,                                     /* mov r1.y, r0.x               */
11021         0x02000001, 0x800f0800, 0x80e40001,                                     /* mov 0C0, r1                  */
11022         0x0000ffff,                                                             /* end                          */
11023     };
11024     struct
11025     {
11026         D3DFORMAT format;
11027         const char *name;
11028     }
11029     formats[] =
11030     {
11031         {D3DFMT_D16_LOCKABLE,   "D3DFMT_D16_LOCKABLE"},
11032         {D3DFMT_D32,            "D3DFMT_D32"},
11033         {D3DFMT_D15S1,          "D3DFMT_D15S1"},
11034         {D3DFMT_D24S8,          "D3DFMT_D24S8"},
11035         {D3DFMT_D24X8,          "D3DFMT_D24X8"},
11036         {D3DFMT_D24X4S4,        "D3DFMT_D24X4S4"},
11037         {D3DFMT_D16,            "D3DFMT_D16"},
11038         {D3DFMT_D32F_LOCKABLE,  "D3DFMT_D32F_LOCKABLE"},
11039         {D3DFMT_D24FS8,         "D3DFMT_D24FS8"},
11040     };
11041     struct
11042     {
11043         float x, y, z;
11044         float s, t, p, q;
11045     }
11046     quad[] =
11047     {
11048         { -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
11049         {  1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
11050         { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
11051         {  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
11052     };
11053     struct
11054     {
11055         UINT x, y;
11056         D3DCOLOR color;
11057     }
11058     expected_colors[] =
11059     {
11060         {400,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11061         {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11062         {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
11063         {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11064         {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
11065         { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11066         { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11067         {240,  60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
11068     };
11069
11070     IDirect3DSurface9 *original_ds, *original_rt, *rt;
11071     IDirect3DPixelShader9 *ps;
11072     IDirect3D9 *d3d9;
11073     D3DCAPS9 caps;
11074     HRESULT hr;
11075     UINT i;
11076
11077     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11078     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11079     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
11080     {
11081         skip("No pixel shader 2.0 support, skipping shadow test.\n");
11082         return;
11083     }
11084
11085     hr = IDirect3DDevice9_GetDirect3D(device, &d3d9);
11086     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11087     hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
11088     ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
11089     hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
11090     ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
11091
11092     hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
11093             D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
11094     ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
11095     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11096     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11097
11098     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
11099     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11100     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
11101     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11102     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
11103     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11104     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
11105     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11106     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11107     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11108
11109     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
11110     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11111     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
11112     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11113     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11114     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11115     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11116     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11117     hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
11118     ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
11119
11120     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
11121     {
11122         D3DFORMAT format = formats[i].format;
11123         IDirect3DTexture9 *texture;
11124         IDirect3DSurface9 *ds;
11125         unsigned int j;
11126
11127         hr = IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11128                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format);
11129         if (FAILED(hr)) continue;
11130
11131         hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
11132                 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
11133         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11134
11135         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
11136         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11137
11138         hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
11139         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11140
11141         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11142         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11143
11144         IDirect3DDevice9_SetPixelShader(device, NULL);
11145         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11146
11147         /* Setup the depth/stencil surface. */
11148         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
11149         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11150
11151         hr = IDirect3DDevice9_BeginScene(device);
11152         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11153         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11154         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11155         hr = IDirect3DDevice9_EndScene(device);
11156         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11157
11158         hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
11159         ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11160         IDirect3DSurface9_Release(ds);
11161
11162         hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
11163         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11164
11165         hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11166         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11167
11168         hr = IDirect3DDevice9_SetPixelShader(device, ps);
11169         ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11170
11171         /* Do the actual shadow mapping. */
11172         hr = IDirect3DDevice9_BeginScene(device);
11173         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11174         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11175         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11176         hr = IDirect3DDevice9_EndScene(device);
11177         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11178
11179         hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11180         ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11181         IDirect3DTexture9_Release(texture);
11182
11183         for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
11184         {
11185             D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
11186             ok(color_match(color, expected_colors[j].color, 0),
11187                     "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
11188                     expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
11189                     formats[i].name, color);
11190         }
11191
11192         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11193         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11194     }
11195
11196     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11197     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11198     IDirect3DPixelShader9_Release(ps);
11199
11200     hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
11201     ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
11202     IDirect3DSurface9_Release(original_ds);
11203
11204     IDirect3DSurface9_Release(original_rt);
11205     IDirect3DSurface9_Release(rt);
11206
11207     IDirect3D9_Release(d3d9);
11208 }
11209
11210 static void fp_special_test(IDirect3DDevice9 *device)
11211 {
11212     static const DWORD vs_header[] =
11213     {
11214         0xfffe0200,                                                             /* vs_2_0                       */
11215         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11216         0x0200001f, 0x80000000, 0x900f0000,                                     /* dcl_position v0              */
11217         0x0200001f, 0x80000005, 0x900f0001,                                     /* dcl_texcoord0 v1             */
11218     };
11219
11220     static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001};         /* log r0.x, v1.x               */
11221     static const DWORD vs_pow[] =
11222             {0x03000020, 0x80010000, 0x90000001, 0x90000001};                   /* pow r0.x, v1.x, v1.x         */
11223     static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001};         /* nrm r0.xyz, v1.x             */
11224     static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001};        /* rcp r0.x, v1.x               */
11225     static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001};        /* rcp r0.x, -v1.x              */
11226     static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001};        /* rsq r0.x, v1.x               */
11227     static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001};        /* rsq r0.x, -v1.x              */
11228
11229     static const DWORD vs_footer[] =
11230     {
11231         0x03000005, 0x80020000, 0x80000000, 0xa0ff0000,                         /* mul r0.y, r0.x, c0.w         */
11232         0x0300000d, 0x80040000, 0x80000000, 0x80550000,                         /* sge r0.z, r0.x, r0.y         */
11233         0x0300000d, 0x80020000, 0x80e40000, 0x80000000,                         /* sge r0.y, r0, r0.x           */
11234         0x03000005, 0x80040000, 0x80550000, 0x80e40000,                         /* mul r0.z, r0.y, r0           */
11235         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11236         0x0300000c, 0x80020000, 0x80000000, 0x80000000,                         /* slt r0.y, r0.x, r0.x         */
11237         0x03000002, 0x80040000, 0x80550000, 0x80550000,                         /* add r0.z, r0.y, r0.y         */
11238         0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000,                         /* slt r0.y, c0.x, r0.w         */
11239         0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000,                         /* max r0.w, -r0.z, r0.z        */
11240         0x03000002, 0x80040000, 0x81550000, 0xa0e40000,                         /* add r0.z, -r0.y, c0          */
11241         0x0300000c, 0x80080000, 0xa0000000, 0x80e40000,                         /* slt r0.w, c0.x, r0           */
11242         0x03000005, 0x80040000, 0x80ff0000, 0x80e40000,                         /* mul r0.z, r0.w, r0           */
11243         0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000,             /* mad r0.y, r0.z, c0, r0       */
11244         0x02000001, 0xe0030000, 0x80e40000,                                     /* mov oT0.xy, r0               */
11245         0x02000001, 0xc00f0000, 0x90e40000,                                     /* mov oPos, v0                 */
11246         0x0000ffff,                                                             /* end                          */
11247     };
11248
11249     static const struct
11250     {
11251         const char *name;
11252         const DWORD *ops;
11253         DWORD size;
11254         D3DCOLOR r600;
11255         D3DCOLOR nv40;
11256         D3DCOLOR nv50;
11257     }
11258     vs_body[] =
11259     {
11260         /* The basic ideas here are:
11261          *     2.0 * +/-INF == +/-INF
11262          *     NAN != NAN
11263          *
11264          * The vertex shader value is written to the red component, with 0.0
11265          * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
11266          * result in 0x00. The pixel shader value is written to the green
11267          * component, but here 0.0 also results in 0x00. The actual value is
11268          * written to the blue component.
11269          *
11270          * There are considerable differences between graphics cards in how
11271          * these are handled, but pow and nrm never generate INF or NAN. */
11272         {"log",     vs_log,     sizeof(vs_log),     0x00000000, 0x00ff0000, 0x00ff7f00},
11273         {"pow",     vs_pow,     sizeof(vs_pow),     0x000000ff, 0x0000ff00, 0x000000ff},
11274         {"nrm",     vs_nrm,     sizeof(vs_nrm),     0x00ff0000, 0x0000ff00, 0x00ff0000},
11275         {"rcp1",    vs_rcp1,    sizeof(vs_rcp1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11276         {"rcp2",    vs_rcp2,    sizeof(vs_rcp2),    0x00000000, 0x00ff0000, 0x00ff7f00},
11277         {"rsq1",    vs_rsq1,    sizeof(vs_rsq1),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11278         {"rsq2",    vs_rsq2,    sizeof(vs_rsq2),    0x000000ff, 0x00ff00ff, 0x00ff7f00},
11279     };
11280
11281     static const DWORD ps_code[] =
11282     {
11283         0xffff0200,                                                             /* ps_2_0                       */
11284         0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0   */
11285         0x0200001f, 0x80000000, 0xb0030000,                                     /* dcl t0.xy                    */
11286         0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000,                         /* max r1.x, t0, c0             */
11287         0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000,                         /* min r0.x, t0, c0             */
11288         0x03000002, 0x80010000, 0x80e40000, 0x81e40001,                         /* add r0.x, r0, -r1            */
11289         0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000,             /* mad r1.x, t0, c0.w. -t0      */
11290         0x02000023, 0x80010002, 0x80e40001,                                     /* abs r2.x, r1                 */
11291         0x02000023, 0x80010000, 0x80e40000,                                     /* abs r0.x, r0                 */
11292         0x02000023, 0x80010001, 0xb0e40000,                                     /* abs r1.x, t0                 */
11293         0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r2, c0.z, c0      */
11294         0x02000023, 0x80010002, 0x80e40002,                                     /* abs r2.x, r2                 */
11295         0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r1.x, -r1, c0.z, c0      */
11296         0x02000023, 0x80010001, 0x80e40001,                                     /* abs r1.x, r1                 */
11297         0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000,             /* cmp r3.x, -r2, c0.z, c0      */
11298         0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000,             /* cmp r2.x, -r1, c0.z, c0      */
11299         0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000,             /* cmp r0.x, -r0, c0.y, c0      */
11300         0x03000005, 0x80010002, 0x80e40002, 0x80e40003,                         /* mul r2.x, r2, r3             */
11301         0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000,             /* cmp r0.x, -r2, c0.z, r0      */
11302         0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000,             /* cmp r0.y, -r1.x, r0.x, c0.x  */
11303         0x02000001, 0x80050000, 0xb0c90000,                                     /* mov r0.xz, t0.yzxw           */
11304         0x02000001, 0x80080000, 0xa0aa0000,                                     /* mov r0.w, c0.z               */
11305         0x02000001, 0x800f0800, 0x80e40000,                                     /* mov oC0, r0                  */
11306         0x0000ffff,                                                             /* end                          */
11307     };
11308
11309     struct
11310     {
11311         float x, y, z;
11312         float s;
11313     }
11314     quad[] =
11315     {
11316         { -1.0f,  1.0f, 0.0f, 0.0f},
11317         {  1.0f,  1.0f, 1.0f, 0.0f},
11318         { -1.0f, -1.0f, 0.0f, 0.0f},
11319         {  1.0f, -1.0f, 1.0f, 0.0f},
11320     };
11321
11322     IDirect3DPixelShader9 *ps;
11323     UINT body_size = 0;
11324     DWORD *vs_code;
11325     D3DCAPS9 caps;
11326     HRESULT hr;
11327     UINT i;
11328
11329     hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11330     ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
11331     if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
11332     {
11333         skip("No shader model 2.0 support, skipping floating point specials test.\n");
11334         return;
11335     }
11336
11337     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
11338     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11339
11340     hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
11341     ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
11342     IDirect3DDevice9_SetPixelShader(device, ps);
11343     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11344
11345     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11346     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11347
11348     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11349     ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11350
11351     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11352     {
11353         if (vs_body[i].size > body_size) body_size = vs_body[i].size;
11354     }
11355
11356     vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
11357     memcpy(vs_code, vs_header, sizeof(vs_header));
11358
11359     for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
11360     {
11361         DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
11362         IDirect3DVertexShader9 *vs;
11363         D3DCOLOR color;
11364
11365         memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
11366         offset += vs_body[i].size / sizeof(*vs_body[i].ops);
11367         memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
11368
11369         hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
11370         ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11371         IDirect3DDevice9_SetVertexShader(device, vs);
11372         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11373
11374         hr = IDirect3DDevice9_BeginScene(device);
11375         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11376         hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11377         ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11378         hr = IDirect3DDevice9_EndScene(device);
11379         ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11380
11381         color = getPixelColor(device, 320, 240);
11382         ok(color_match(color, vs_body[i].r600, 1)
11383                 || color_match(color, vs_body[i].nv40, 1)
11384                 || color_match(color, vs_body[i].nv50, 1),
11385                 "Expected color 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
11386                 vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
11387
11388         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11389         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11390
11391         hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11392         ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11393         IDirect3DVertexShader9_Release(vs);
11394     }
11395
11396     HeapFree(GetProcessHeap(), 0, vs_code);
11397
11398     hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11399     ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
11400     IDirect3DPixelShader9_Release(ps);
11401 }
11402
11403 static void srgbwrite_format_test(IDirect3DDevice9 *device)
11404 {
11405     IDirect3D9 *d3d;
11406     IDirect3DSurface9 *rt, *backbuffer;
11407     IDirect3DTexture9 *texture;
11408     HRESULT hr;
11409     int i;
11410     DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
11411     static const struct
11412     {
11413         D3DFORMAT fmt;
11414         const char *name;
11415     }
11416     formats[] =
11417     {
11418         { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
11419         { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
11420         { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
11421         { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
11422         { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
11423     };
11424     static const struct
11425     {
11426         float x, y, z;
11427         float u, v;
11428     }
11429     quad[] =
11430     {
11431         {-1.0f,  -1.0f,  0.1f,   0.0f,   0.0f},
11432         {-1.0f,   1.0f,  0.1f,   1.0f,   0.0f},
11433         { 1.0f,  -1.0f,  0.1f,   0.0f,   1.0f},
11434         { 1.0f,   1.0f,  0.1f,   1.0f,   1.0f}
11435     };
11436
11437     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
11438     ok(SUCCEEDED(hr), "GetDirect3D failed, hr %#x.\n", hr);
11439     hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11440     ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
11441     hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11442     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
11443     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11444     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11445     hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
11446     ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11447
11448     for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
11449     {
11450         if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11451                 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
11452         {
11453             skip("Format %s not supported as render target, skipping test.\n",
11454                     formats[i].name);
11455             continue;
11456         }
11457
11458         hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET, formats[i].fmt,
11459                                             D3DPOOL_DEFAULT, &texture, NULL);
11460         ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
11461         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11462         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11463
11464         hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
11465         ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
11466         hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
11467         ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11468         hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
11469         ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
11470
11471         hr = IDirect3DDevice9_BeginScene(device);
11472         ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11473         if(SUCCEEDED(hr))
11474         {
11475             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
11476             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11477             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11478             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11479             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11480             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11481
11482             hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
11483             ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
11484             hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11485             ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
11486             hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
11487             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11488             hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11489             ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11490             hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11491             ok(SUCCEEDED(hr), "DrawPrimitive failed, hr %#x.\n", hr);
11492             hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
11493             ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
11494
11495             hr = IDirect3DDevice9_EndScene(device);
11496             ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11497         }
11498
11499         IDirect3DSurface9_Release(rt);
11500         IDirect3DTexture9_Release(texture);
11501
11502         color = getPixelColor(device, 360, 240);
11503         if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11504                                     D3DUSAGE_QUERY_SRGBWRITE,
11505                                     D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
11506         {
11507             /* Big slop for R5G6B5 */
11508             ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
11509                 formats[i].name, color_srgb, color);
11510         }
11511         else
11512         {
11513             /* Big slop for R5G6B5 */
11514             ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
11515                 formats[i].name, color_rgb, color);
11516         }
11517
11518         hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11519         ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
11520     }
11521
11522     hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
11523     ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
11524
11525     IDirect3D9_Release(d3d);
11526     IDirect3DSurface9_Release(backbuffer);
11527 }
11528
11529 START_TEST(visual)
11530 {
11531     IDirect3DDevice9 *device_ptr;
11532     D3DCAPS9 caps;
11533     HRESULT hr;
11534     DWORD color;
11535
11536     d3d9_handle = LoadLibraryA("d3d9.dll");
11537     if (!d3d9_handle)
11538     {
11539         skip("Could not load d3d9.dll\n");
11540         return;
11541     }
11542
11543     device_ptr = init_d3d9();
11544     if (!device_ptr)
11545     {
11546         skip("Creating the device failed\n");
11547         return;
11548     }
11549
11550     IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
11551
11552     /* Check for the reliability of the returned data */
11553     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11554     if(FAILED(hr))
11555     {
11556         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11557         goto cleanup;
11558     }
11559
11560     color = getPixelColor(device_ptr, 1, 1);
11561     if(color !=0x00ff0000)
11562     {
11563         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11564         goto cleanup;
11565     }
11566     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11567
11568     hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
11569     if(FAILED(hr))
11570     {
11571         skip("Clear failed, can't assure correctness of the test results, skipping\n");
11572         goto cleanup;
11573     }
11574
11575     color = getPixelColor(device_ptr, 639, 479);
11576     if(color != 0x0000ddee)
11577     {
11578         skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
11579         goto cleanup;
11580     }
11581     IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
11582
11583     /* Now execute the real tests */
11584     depth_clamp_test(device_ptr);
11585     stretchrect_test(device_ptr);
11586     lighting_test(device_ptr);
11587     clear_test(device_ptr);
11588     color_fill_test(device_ptr);
11589     fog_test(device_ptr);
11590     if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
11591     {
11592         test_cube_wrap(device_ptr);
11593     } else {
11594         skip("No cube texture support\n");
11595     }
11596     z_range_test(device_ptr);
11597     if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
11598     {
11599         maxmip_test(device_ptr);
11600     }
11601     else
11602     {
11603         skip("No mipmap support\n");
11604     }
11605     offscreen_test(device_ptr);
11606     alpha_test(device_ptr);
11607     shademode_test(device_ptr);
11608     srgbtexture_test(device_ptr);
11609     release_buffer_test(device_ptr);
11610     float_texture_test(device_ptr);
11611     g16r16_texture_test(device_ptr);
11612     pixelshader_blending_test(device_ptr);
11613     texture_transform_flags_test(device_ptr);
11614     autogen_mipmap_test(device_ptr);
11615     fixed_function_decl_test(device_ptr);
11616     conditional_np2_repeat_test(device_ptr);
11617     fixed_function_bumpmap_test(device_ptr);
11618     if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
11619         stencil_cull_test(device_ptr);
11620     } else {
11621         skip("No two sided stencil support\n");
11622     }
11623     pointsize_test(device_ptr);
11624     tssargtemp_test(device_ptr);
11625     np2_stretch_rect_test(device_ptr);
11626     yuv_color_test(device_ptr);
11627     zwriteenable_test(device_ptr);
11628     alphatest_test(device_ptr);
11629     viewport_test(device_ptr);
11630
11631     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11632     {
11633         test_constant_clamp_vs(device_ptr);
11634         test_compare_instructions(device_ptr);
11635     }
11636     else skip("No vs_1_1 support\n");
11637
11638     if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
11639     {
11640         test_mova(device_ptr);
11641         loop_index_test(device_ptr);
11642         sincos_test(device_ptr);
11643         sgn_test(device_ptr);
11644         if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11645             test_vshader_input(device_ptr);
11646             test_vshader_float16(device_ptr);
11647             stream_test(device_ptr);
11648         } else {
11649             skip("No vs_3_0 support\n");
11650         }
11651     }
11652     else skip("No vs_2_0 support\n");
11653
11654     if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11655     {
11656         fog_with_shader_test(device_ptr);
11657     }
11658     else skip("No vs_1_1 and ps_1_1 support\n");
11659
11660     if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
11661     {
11662         texbem_test(device_ptr);
11663         texdepth_test(device_ptr);
11664         texkill_test(device_ptr);
11665         x8l8v8u8_test(device_ptr);
11666         if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
11667             constant_clamp_ps_test(device_ptr);
11668             cnd_test(device_ptr);
11669             if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
11670                 dp2add_ps_test(device_ptr);
11671                 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
11672                     nested_loop_test(device_ptr);
11673                     fixed_function_varying_test(device_ptr);
11674                     vFace_register_test(device_ptr);
11675                     vpos_register_test(device_ptr);
11676                     multiple_rendertargets_test(device_ptr);
11677                 } else {
11678                     skip("No ps_3_0 or vs_3_0 support\n");
11679                 }
11680             } else {
11681                 skip("No ps_2_0 support\n");
11682             }
11683         }
11684     }
11685     else skip("No ps_1_1 support\n");
11686
11687     texop_test(device_ptr);
11688     texop_range_test(device_ptr);
11689     alphareplicate_test(device_ptr);
11690     dp3_alpha_test(device_ptr);
11691     depth_buffer_test(device_ptr);
11692     intz_test(device_ptr);
11693     shadow_test(device_ptr);
11694     fp_special_test(device_ptr);
11695     depth_bounds_test(device_ptr);
11696     srgbwrite_format_test(device_ptr);
11697
11698 cleanup:
11699     if(device_ptr) {
11700         D3DPRESENT_PARAMETERS present_parameters;
11701         IDirect3DSwapChain9 *swapchain;
11702         ULONG ref;
11703
11704         IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
11705         IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
11706         IDirect3DSwapChain9_Release(swapchain);
11707         ref = IDirect3DDevice9_Release(device_ptr);
11708         ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);
11709         DestroyWindow(present_parameters.hDeviceWindow);
11710     }
11711 }